diff --git a/cli/manager.go b/cli/manager.go new file mode 100644 index 00000000..c002f2f3 --- /dev/null +++ b/cli/manager.go @@ -0,0 +1,68 @@ +// Copyright (c) Ultraviolet +// SPDX-License-Identifier: Apache-2.0 +package cli + +import ( + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/ultravioletrs/cocos/manager" + "google.golang.org/protobuf/types/known/emptypb" +) + +func (c *CLI) NewCreateVMCmd() *cobra.Command { + return &cobra.Command{ + Use: "create-vm", + Short: "Create a new virtual machine", + Example: `create-vm`, + Args: cobra.ExactArgs(0), + Run: func(cmd *cobra.Command, args []string) { + if err := c.InitializeManagerClient(cmd); err == nil { + defer c.Close() + } + + if c.connectErr != nil { + printError(cmd, "Failed to connect to manager: %v ❌ ", c.connectErr) + return + } + + cmd.Println("🔗 Creating a new virtual machine") + + res, err := c.managerClient.CreateVm(cmd.Context(), &emptypb.Empty{}) + if err != nil { + printError(cmd, "Error creating virtual machine: %v ❌ ", err) + return + } + + cmd.Println(color.New(color.FgGreen).Sprintf("✅ Virtual machine created successfully with id %s and port %s", res.SvmId, res.ForwardedPort)) + }, + } +} + +func (c *CLI) NewRemoveVMCmd() *cobra.Command { + return &cobra.Command{ + Use: "remove-vm", + Short: "Remove a virtual machine", + Example: `remove-vm `, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + if err := c.InitializeManagerClient(cmd); err == nil { + defer c.Close() + } + + if c.connectErr != nil { + printError(cmd, "Failed to connect to manager: %v ❌ ", c.connectErr) + return + } + + cmd.Println("🔗 Removing virtual machine") + + _, err := c.managerClient.RemoveVm(cmd.Context(), &manager.RemoveReq{SvmId: args[0]}) + if err != nil { + printError(cmd, "Error removing virtual machine: %v ❌ ", err) + return + } + + cmd.Println(color.New(color.FgGreen).Sprintf("✅ Virtual machine removed successfully")) + }, + } +} diff --git a/cli/sdk.go b/cli/sdk.go index 672cf500..76eebf78 100644 --- a/cli/sdk.go +++ b/cli/sdk.go @@ -6,28 +6,33 @@ import ( "context" "github.com/spf13/cobra" + "github.com/ultravioletrs/cocos/manager" "github.com/ultravioletrs/cocos/pkg/clients/grpc" "github.com/ultravioletrs/cocos/pkg/clients/grpc/agent" + managergrpc "github.com/ultravioletrs/cocos/pkg/clients/grpc/manager" "github.com/ultravioletrs/cocos/pkg/sdk" ) var Verbose bool type CLI struct { - agentSDK sdk.SDK - config grpc.AgentClientConfig - client grpc.Client - connectErr error + agentSDK sdk.SDK + agentConfig grpc.AgentClientConfig + managerConfig grpc.ManagerClientConfig + client grpc.Client + managerClient manager.ManagerServiceClient + connectErr error } -func New(config grpc.AgentClientConfig) *CLI { +func New(agentConfig grpc.AgentClientConfig, managerConfig grpc.ManagerClientConfig) *CLI { return &CLI{ - config: config, + agentConfig: agentConfig, + managerConfig: managerConfig, } } -func (c *CLI) InitializeSDK(cmd *cobra.Command) error { - agentGRPCClient, agentClient, err := agent.NewAgentClient(context.Background(), c.config) +func (c *CLI) InitializeAgentSDK(cmd *cobra.Command) error { + agentGRPCClient, agentClient, err := agent.NewAgentClient(context.Background(), c.agentConfig) if err != nil { c.connectErr = err return err @@ -39,6 +44,20 @@ func (c *CLI) InitializeSDK(cmd *cobra.Command) error { return nil } +func (c *CLI) InitializeManagerClient(cmd *cobra.Command) error { + managerGRPCClient, managerClient, err := managergrpc.NewManagerClient(c.managerConfig) + if err != nil { + c.connectErr = err + return err + } + + cmd.Println("🔗 Connected to manager using ", managerGRPCClient.Secure()) + c.client = managerGRPCClient + + c.managerClient = managerClient + return nil +} + func (c *CLI) Close() { c.client.Close() } diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 916e3703..ace4d1a0 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -19,11 +19,12 @@ import ( ) const ( - svcName = "cli" - envPrefixAgentGRPC = "AGENT_GRPC_" - completion = "completion" - filePermision = 0o755 - cocosDirectory = ".cocos" + svcName = "cli" + envPrefixAgentGRPC = "AGENT_GRPC_" + envPrefixManagerGRPC = "MANAGER_GRPC_" + completion = "completion" + filePermision = 0o755 + cocosDirectory = ".cocos" ) type config struct { @@ -98,9 +99,16 @@ func main() { return } - cliSVC := cli.New(agentGRPCConfig) + managerGRPCConfig := grpc.ManagerClientConfig{} + if err := env.ParseWithOptions(&managerGRPCConfig, env.Options{Prefix: envPrefixManagerGRPC}); err != nil { + message := color.New(color.FgRed).Sprintf("failed to load %s gRPC client configuration : %s", svcName, err) + rootCmd.Println(message) + return + } + + cliSVC := cli.New(agentGRPCConfig, managerGRPCConfig) - if err := cliSVC.InitializeSDK(rootCmd); err == nil { + if err := cliSVC.InitializeAgentSDK(rootCmd); err == nil { defer cliSVC.Close() } @@ -119,6 +127,8 @@ func main() { rootCmd.AddCommand(attestationPolicyCmd) rootCmd.AddCommand(keysCmd) rootCmd.AddCommand(cliSVC.NewCABundleCmd(directoryCachePath)) + rootCmd.AddCommand(cliSVC.NewCreateVMCmd()) + rootCmd.AddCommand(cliSVC.NewRemoveVMCmd()) // Attestation commands attestationCmd.AddCommand(cliSVC.NewGetAttestationCmd()) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 25fd7aa8..b143bb67 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -10,25 +10,24 @@ import ( "log/slog" "net/url" "os" - "os/signal" "strings" - "syscall" mglog "github.com/absmach/magistrala/logger" "github.com/absmach/magistrala/pkg/jaeger" "github.com/absmach/magistrala/pkg/prometheus" "github.com/absmach/magistrala/pkg/uuid" "github.com/caarlos0/env/v11" + "github.com/ultravioletrs/cocos/internal/server" + grpcserver "github.com/ultravioletrs/cocos/internal/server/grpc" "github.com/ultravioletrs/cocos/manager" "github.com/ultravioletrs/cocos/manager/api" - managerapi "github.com/ultravioletrs/cocos/manager/api/grpc" - "github.com/ultravioletrs/cocos/manager/events" + managergrpc "github.com/ultravioletrs/cocos/manager/api/grpc" "github.com/ultravioletrs/cocos/manager/qemu" "github.com/ultravioletrs/cocos/manager/tracing" - pkggrpc "github.com/ultravioletrs/cocos/pkg/clients/grpc" - managergrpc "github.com/ultravioletrs/cocos/pkg/clients/grpc/manager" "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" ) const ( @@ -92,64 +91,33 @@ func main() { args := qemuCfg.ConstructQemuArgs() logger.Info(strings.Join(args, " ")) - managerGRPCConfig := pkggrpc.CVMClientConfig{} + managerGRPCConfig := server.ServerConfig{} if err := env.ParseWithOptions(&managerGRPCConfig, env.Options{Prefix: envPrefixGRPC}); err != nil { logger.Error(fmt.Sprintf("failed to load %s gRPC client configuration : %s", svcName, err)) exitCode = 1 return } - managerGRPCClient, managerClient, err := managergrpc.NewManagerClient(managerGRPCConfig) + svc, err := newService(logger, tracer, qemuCfg, cfg.AttestationPolicyBinary, cfg.EosVersion) if err != nil { logger.Error(err.Error()) exitCode = 1 return } - defer managerGRPCClient.Close() - pc, err := managerClient.Process(ctx) - if err != nil { - logger.Error(err.Error()) - exitCode = 1 - return - } - - eventsChan := make(chan *manager.ClientStreamMessage, clientBufferSize) - svc, err := newService(logger, tracer, qemuCfg, eventsChan, cfg.AttestationPolicyBinary, cfg.EosVersion) - if err != nil { - logger.Error(err.Error()) - exitCode = 1 - return + registerManagerServiceServer := func(srv *grpc.Server) { + reflection.Register(srv) + manager.RegisterManagerServiceServer(srv, managergrpc.NewServer(svc)) } - eventsSvc, err := events.New(logger, svc.ReportBrokenConnection, eventsChan) - if err != nil { - logger.Error(err.Error()) - exitCode = 1 - return - } - - go eventsSvc.Listen(ctx) - - mc := managerapi.NewClient(pc, svc, eventsChan, logger) + gs := grpcserver.New(ctx, cancel, svcName, managerGRPCConfig, registerManagerServiceServer, logger, nil, nil) g.Go(func() error { - ch := make(chan os.Signal, 1) - signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) - defer signal.Stop(ch) - - select { - case <-ch: - logger.Info("Received signal, shutting down...") - cancel() - return nil - case <-ctx.Done(): - return ctx.Err() - } + return gs.Start() }) g.Go(func() error { - return mc.Process(ctx, cancel) + return server.StopHandler(ctx, cancel, logger, svcName, gs) }) if err := g.Wait(); err != nil { @@ -157,8 +125,8 @@ func main() { } } -func newService(logger *slog.Logger, tracer trace.Tracer, qemuCfg qemu.Config, eventsChan chan *manager.ClientStreamMessage, attestationPolicyPath string, eosVersion string) (manager.Service, error) { - svc, err := manager.New(qemuCfg, attestationPolicyPath, logger, eventsChan, qemu.NewVM, eosVersion) +func newService(logger *slog.Logger, tracer trace.Tracer, qemuCfg qemu.Config, attestationPolicyPath string, eosVersion string) (manager.Service, error) { + svc, err := manager.New(qemuCfg, attestationPolicyPath, logger, qemu.NewVM, eosVersion) if err != nil { return nil, err } diff --git a/go.mod b/go.mod index cab10500..c2ded98f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.23.0 require ( github.com/absmach/magistrala v0.15.1 github.com/caarlos0/env/v11 v11.2.2 - github.com/cenkalti/backoff/v4 v4.3.0 github.com/fatih/color v1.18.0 github.com/go-kit/kit v0.13.0 github.com/gofrs/uuid v4.4.0+incompatible @@ -25,6 +24,7 @@ require ( require ( github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -59,7 +59,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-configfs-tsm v0.2.2 // indirect github.com/google/logger v1.1.1 - github.com/google/uuid v1.6.0 // indirect + github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mdlayher/socket v0.4.1 // indirect diff --git a/internal/vsock/client.go b/internal/vsock/client.go deleted file mode 100644 index 92c60c72..00000000 --- a/internal/vsock/client.go +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 - -package vsock - -import ( - "context" - "encoding/binary" - "fmt" - "io" - "log" - "net" - "sync" - "sync/atomic" - "time" - - "google.golang.org/protobuf/proto" -) - -const ( - maxRetries = 3 - retryDelay = time.Second - maxMessageSize = 1 << 20 // 1 MB - ackTimeout = 5 * time.Second - maxConcurrent = 100 -) - -type MessageStatus int - -const ( - StatusPending MessageStatus = iota - StatusSent - StatusAcknowledged - StatusFailed -) - -type Message struct { - ID uint32 - Content []byte - Status MessageStatus - Retries int -} - -type AckWriter struct { - conn net.Conn - pendingMessages chan *Message - messageStore sync.Map // map[uint32]*Message - nextID uint32 - ctx context.Context - cancel context.CancelFunc - wg sync.WaitGroup -} - -func NewAckWriter(conn net.Conn) io.WriteCloser { - ctx, cancel := context.WithCancel(context.Background()) - aw := &AckWriter{ - conn: conn, - pendingMessages: make(chan *Message, maxConcurrent), - nextID: 1, - ctx: ctx, - cancel: cancel, - } - aw.wg.Add(2) - go aw.sendMessages() - go aw.handleAcknowledgments() - return aw -} - -func (aw *AckWriter) Write(p []byte) (int, error) { - if len(p) > maxMessageSize { - return 0, fmt.Errorf("message size exceeds maximum allowed size of %d bytes", maxMessageSize) - } - - messageID := atomic.AddUint32(&aw.nextID, 1) - message := &Message{ - ID: messageID, - Content: make([]byte, len(p)), - Status: StatusPending, - } - copy(message.Content, p) - - aw.messageStore.Store(messageID, message) - select { - case aw.pendingMessages <- message: - return len(p), nil - case <-aw.ctx.Done(): - return 0, fmt.Errorf("writer is closed") - } -} - -func (aw *AckWriter) sendMessages() { - defer aw.wg.Done() - - for { - select { - case <-aw.ctx.Done(): - return - case msg := <-aw.pendingMessages: - if err := aw.sendWithRetry(msg); err != nil { - log.Printf("Failed to send message %d after all retries: %v", msg.ID, err) - msg.Status = StatusFailed - aw.messageStore.Store(msg.ID, msg) - } - } - } -} - -func (aw *AckWriter) sendWithRetry(msg *Message) error { - for msg.Retries < maxRetries { - if err := aw.writeMessage(msg.ID, msg.Content); err != nil { - msg.Retries++ - msg.Status = StatusPending - log.Printf("Error writing message %d (attempt %d): %v", msg.ID, msg.Retries, err) - time.Sleep(retryDelay) - continue - } - msg.Status = StatusSent - aw.messageStore.Store(msg.ID, msg) - return nil - } - return fmt.Errorf("max retries reached") -} - -func (aw *AckWriter) writeMessage(messageID uint32, p []byte) error { - if err := binary.Write(aw.conn, binary.LittleEndian, messageID); err != nil { - return fmt.Errorf("failed to write message ID: %w", err) - } - - messageLen := uint32(len(p)) - if err := binary.Write(aw.conn, binary.LittleEndian, messageLen); err != nil { - return fmt.Errorf("failed to write message length: %w", err) - } - - if _, err := aw.conn.Write(p); err != nil { - return fmt.Errorf("failed to write message content: %w", err) - } - - return nil -} - -func (aw *AckWriter) handleAcknowledgments() { - defer aw.wg.Done() - - for { - select { - case <-aw.ctx.Done(): - return - default: - var ackID uint32 - if err := binary.Read(aw.conn, binary.LittleEndian, &ackID); err != nil { - if err == io.EOF { - log.Println("Connection closed, stopping acknowledgment handler") - return - } - log.Printf("Error reading ACK: %v", err) - time.Sleep(retryDelay) - continue - } - - if msg, ok := aw.messageStore.Load(ackID); ok { - m := msg.(*Message) - m.Status = StatusAcknowledged - aw.messageStore.Store(ackID, m) - - // Clean up old messages periodically - go aw.cleanupOldMessages(ackID) - } else { - log.Printf("Received ACK for unknown message ID: %d", ackID) - } - } - } -} - -func (aw *AckWriter) cleanupOldMessages(currentID uint32) { - aw.messageStore.Range(func(key, value interface{}) bool { - msgID := key.(uint32) - msg := value.(*Message) - - // Clean up acknowledged messages that are old - if msg.Status == StatusAcknowledged && msgID < currentID-maxConcurrent { - aw.messageStore.Delete(msgID) - } - return true - }) -} - -func (aw *AckWriter) Close() error { - aw.cancel() - aw.wg.Wait() - return aw.conn.Close() -} - -type Reader interface { - Read() ([]byte, error) - ReadProto(msg proto.Message) error -} - -type AckReader struct { - conn net.Conn - ctx context.Context -} - -func NewAckReader(conn net.Conn) Reader { - return &AckReader{ - conn: conn, - ctx: context.Background(), - } -} - -func (ar *AckReader) ReadProto(msg proto.Message) error { - data, err := ar.Read() - if err != nil { - return fmt.Errorf("failed to read proto message: %w", err) - } - return proto.Unmarshal(data, msg) -} - -func (ar *AckReader) Read() ([]byte, error) { - var messageID uint32 - if err := binary.Read(ar.conn, binary.LittleEndian, &messageID); err != nil { - return nil, fmt.Errorf("error reading message ID: %w", err) - } - - var messageLen uint32 - if err := binary.Read(ar.conn, binary.LittleEndian, &messageLen); err != nil { - return nil, fmt.Errorf("error reading message length: %w", err) - } - - if messageLen > maxMessageSize { - return nil, fmt.Errorf("message size %d exceeds maximum allowed size of %d bytes", messageLen, maxMessageSize) - } - - data := make([]byte, messageLen) - if _, err := io.ReadFull(ar.conn, data); err != nil { - return nil, fmt.Errorf("error reading message content: %w", err) - } - - if err := ar.sendAck(messageID); err != nil { - return nil, fmt.Errorf("error sending ACK: %w", err) - } - - return data, nil -} - -func (ar *AckReader) sendAck(messageID uint32) error { - return binary.Write(ar.conn, binary.LittleEndian, messageID) -} diff --git a/internal/vsock/client_test.go b/internal/vsock/client_test.go deleted file mode 100644 index 7412073d..00000000 --- a/internal/vsock/client_test.go +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package vsock - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "net" - "sync" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/ultravioletrs/cocos/manager" - "google.golang.org/protobuf/proto" -) - -// MockConn implements net.Conn for testing purposes. -type MockConn struct { - ReadData []byte - WrittenData []byte - ReadErr error - WriteErr error - closed bool - mu sync.Mutex -} - -func (m *MockConn) Read(b []byte) (n int, err error) { - m.mu.Lock() - defer m.mu.Unlock() - if m.closed { - return 0, io.EOF - } - if len(m.ReadData) == 0 { - return 0, io.EOF // Ensure we handle this case more predictably - } - if m.ReadErr != nil { - return 0, m.ReadErr - } - n = copy(b, m.ReadData) - m.ReadData = m.ReadData[n:] - return n, nil -} - -func (m *MockConn) Write(b []byte) (n int, err error) { - m.mu.Lock() - defer m.mu.Unlock() - if m.closed { - return 0, errors.New("connection closed") - } - if m.WriteErr != nil { - return 0, m.WriteErr - } - m.WrittenData = append(m.WrittenData, b...) - return len(b), nil -} - -func (m *MockConn) Close() error { - m.mu.Lock() - defer m.mu.Unlock() - m.closed = true - return nil -} - -// Implement other net.Conn methods with empty implementations. -func (m *MockConn) LocalAddr() net.Addr { return nil } -func (m *MockConn) RemoteAddr() net.Addr { return nil } -func (m *MockConn) SetDeadline(t time.Time) error { return nil } -func (m *MockConn) SetReadDeadline(t time.Time) error { return nil } -func (m *MockConn) SetWriteDeadline(t time.Time) error { return nil } - -func TestAckReader_Read(t *testing.T) { - tests := []struct { - name string - data []byte - wantErr bool - }{ - {"Valid message", []byte("Hello, World!"), false}, - {"Empty message", []byte{}, false}, - {"Message at max size", make([]byte, maxMessageSize), false}, - {"Message exceeds max size", make([]byte, maxMessageSize+1), true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - mockConn := &MockConn{} - ar := NewAckReader(mockConn) - - // Prepare mock data - messageID := uint32(1) - messageLen := uint32(len(tt.data)) - mockData := make([]byte, 8+len(tt.data)) - binary.LittleEndian.PutUint32(mockData[:4], messageID) - binary.LittleEndian.PutUint32(mockData[4:8], messageLen) - copy(mockData[8:], tt.data) - mockConn.ReadData = mockData - - data, err := ar.Read() - - if (err != nil) != tt.wantErr { - t.Errorf("AckReader.Read() error = %v, wantErr %v", err, tt.wantErr) - return - } - - if !tt.wantErr { - if !bytes.Equal(data, tt.data) { - t.Errorf("AckReader.Read() got = %v, want %v", data, tt.data) - } - - // Check if ACK was sent - if len(mockConn.WrittenData) != 4 { - t.Errorf("AckReader.Read() did not send ACK") - } else { - ackID := binary.LittleEndian.Uint32(mockConn.WrittenData) - if ackID != messageID { - t.Errorf("AckReader.Read() sent wrong ACK ID, got %d, want %d", ackID, messageID) - } - } - } - }) - } -} - -func TestAckReader_ReadProto(t *testing.T) { - tests := []struct { - name string - msg *manager.ClientStreamMessage - wantErr bool - }{ - {"Valid proto message", &manager.ClientStreamMessage{}, false}, - {"Empty proto message", &manager.ClientStreamMessage{}, false}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - mockConn := &MockConn{} - ar := NewAckReader(mockConn) - - // Prepare mock data - protoData, _ := proto.Marshal(tt.msg) - messageID := uint32(1) - messageLen := uint32(len(protoData)) - mockData := make([]byte, 8+len(protoData)) - binary.LittleEndian.PutUint32(mockData[:4], messageID) - binary.LittleEndian.PutUint32(mockData[4:8], messageLen) - copy(mockData[8:], protoData) - mockConn.ReadData = mockData - - receivedMsg := &manager.ClientStreamMessage{} - err := ar.ReadProto(receivedMsg) - - if (err != nil) != tt.wantErr { - t.Errorf("AckReader.ReadProto() error = %v, wantErr %v", err, tt.wantErr) - return - } - - if !tt.wantErr { - if receivedMsg.Message != tt.msg.Message { - t.Errorf("AckReader.ReadProto() got = %v, want %v", receivedMsg, tt.msg) - } - - // Check if ACK was sent - if len(mockConn.WrittenData) != 4 { - t.Errorf("AckReader.ReadProto() did not send ACK") - } else { - ackID := binary.LittleEndian.Uint32(mockConn.WrittenData) - if ackID != messageID { - t.Errorf("AckReader.ReadProto() sent wrong ACK ID, got %d, want %d", ackID, messageID) - } - } - } - }) - } -} - -func TestNewAckWriter(t *testing.T) { - mockConn := &MockConn{} - writer := NewAckWriter(mockConn) - - if _, ok := writer.(io.Writer); !ok { - t.Errorf("NewAckWriter() did not return an io.Writer") - } -} - -func TestNewAckReader(t *testing.T) { - mockConn := &MockConn{} - reader := NewAckReader(mockConn) - - assert.NotNil(t, reader) -} - -func TestAckWriter_Close(t *testing.T) { - mockConn := &MockConn{} - aw := NewAckWriter(mockConn) - - err := aw.Close() - if err != nil { - t.Errorf("AckWriter.Close() error = %v, wantErr %v", err, nil) - } - - if !mockConn.closed { - t.Errorf("AckWriter.Close() did not close the connection") - } -} - -func TestAckWriter_Write(t *testing.T) { - tests := []struct { - name string - input []byte - expectErr bool - expectedError string - }{ - { - name: "Message exceeds max size", - input: make([]byte, maxMessageSize+1), - expectErr: true, - expectedError: "message size exceeds maximum allowed size", - }, - { - name: "Write succeeds", - input: []byte("Hello, world!"), - expectErr: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - mockConn := &MockConn{ - mu: sync.Mutex{}, - } - - writer := NewAckWriter(mockConn) - defer writer.Close() - - if tt.expectErr { - writer.(*AckWriter).ctx.Done() - } - - time.Sleep(100 * time.Millisecond) - - n, err := writer.Write(tt.input) - - if tt.expectErr { - assert.Error(t, err) - if tt.expectedError != "" { - assert.Contains(t, err.Error(), tt.expectedError) - } - assert.Zero(t, n) - } else { - assert.NoError(t, err) - assert.Equal(t, len(tt.input), n) - } - }) - } -} - -func TestAckWriter_CleanupOldMessages(t *testing.T) { - mockConn := &MockConn{} - writer := NewAckWriter(mockConn).(*AckWriter) - defer writer.Close() - - for i := uint32(1); i <= maxConcurrent+10; i++ { - msg := &Message{ - ID: i, - Content: []byte("test"), - Status: StatusAcknowledged, - } - writer.messageStore.Store(i, msg) - } - - writer.cleanupOldMessages(maxConcurrent + 11) - - var count int - writer.messageStore.Range(func(key, value interface{}) bool { - count++ - return true - }) - - assert.LessOrEqual(t, count, maxConcurrent) -} - -func TestAckReader_LargeMessage(t *testing.T) { - mockConn := &MockConn{} - reader := NewAckReader(mockConn) - - largeMessage := make([]byte, maxMessageSize-1) - for i := range largeMessage { - largeMessage[i] = byte(i % 256) - } - - messageID := uint32(1) - messageLen := uint32(len(largeMessage)) - mockData := make([]byte, 8+len(largeMessage)) - binary.LittleEndian.PutUint32(mockData[:4], messageID) - binary.LittleEndian.PutUint32(mockData[4:8], messageLen) - copy(mockData[8:], largeMessage) - mockConn.ReadData = mockData - - data, err := reader.Read() - assert.NoError(t, err) - assert.Equal(t, largeMessage, data) - - assert.Equal(t, 4, len(mockConn.WrittenData)) - ackID := binary.LittleEndian.Uint32(mockConn.WrittenData) - assert.Equal(t, messageID, ackID) -} - -func TestAckWriter_FailedSends(t *testing.T) { - mockConn := &MockConn{ - WriteErr: errors.New("write error"), - } - writer := NewAckWriter(mockConn).(*AckWriter) - defer writer.Close() - - // Add some messages to the channel - for i := 0; i < 5; i++ { - msg := &Message{ - ID: uint32(i + 1), - Content: []byte(fmt.Sprintf("Message %d", i+1)), - Status: StatusPending, - } - writer.pendingMessages <- msg - } - - // Wait for the messages to be sent - time.Sleep(100 * time.Millisecond) - - // Check that the messages were marked as failed - writer.messageStore.Range(func(key, value interface{}) bool { - msg := value.(*Message) - assert.Equal(t, StatusFailed, msg.Status) - return true - }) -} diff --git a/manager/agentEventsLogs.go b/manager/agentEventsLogs.go deleted file mode 100644 index b1b2484e..00000000 --- a/manager/agentEventsLogs.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package manager - -import ( - "fmt" - "regexp" - "strconv" - - "github.com/ultravioletrs/cocos/pkg/manager" - "google.golang.org/protobuf/types/known/timestamppb" -) - -var ( - errFailedToParseCID = fmt.Errorf("failed to parse computation ID") - errComputationNotFound = fmt.Errorf("computation not found") -) - -func (ms *managerService) computationIDFromAddress(address string) (string, error) { - re := regexp.MustCompile(`vm\((\d+)\)`) - matches := re.FindStringSubmatch(address) - - if len(matches) > 1 { - cid, err := strconv.Atoi(matches[1]) - if err != nil { - return "", err - } - return ms.findComputationID(cid) - } - return "", errFailedToParseCID -} - -func (ms *managerService) findComputationID(cid int) (string, error) { - ms.mu.Lock() - defer ms.mu.Unlock() - for cmpID, vm := range ms.vms { - if vm.GetCID() == cid { - return cmpID, nil - } - } - - return "", errComputationNotFound -} - -func (ms *managerService) reportBrokenConnection(cmpID string) { - ms.eventsChan <- &ClientStreamMessage{ - Message: &ClientStreamMessage_AgentEvent{ - AgentEvent: &AgentEvent{ - EventType: ms.vms[cmpID].State(), - ComputationId: cmpID, - Status: manager.Disconnected.String(), - Timestamp: timestamppb.Now(), - Originator: "manager", - }, - }, - } -} - -func (ms *managerService) ReportBrokenConnection(addr string) { - cmpID, err := ms.computationIDFromAddress(addr) - if err != nil { - ms.logger.Warn(err.Error()) - return - } - ms.reportBrokenConnection(cmpID) -} diff --git a/manager/agentEventsLogs_test.go b/manager/agentEventsLogs_test.go deleted file mode 100644 index f8b67c12..00000000 --- a/manager/agentEventsLogs_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package manager - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/ultravioletrs/cocos/manager/qemu" - "github.com/ultravioletrs/cocos/manager/vm" - "github.com/ultravioletrs/cocos/pkg/manager" -) - -func TestComputationIDFromAddress(t *testing.T) { - ms := &managerService{ - vms: map[string]vm.VM{ - "comp1": qemu.NewVM(qemu.VMInfo{Config: qemu.Config{VSockConfig: qemu.VSockConfig{GuestCID: 3}}}, func(event interface{}) error { return nil }, "comp1"), - "comp2": qemu.NewVM(qemu.VMInfo{Config: qemu.Config{VSockConfig: qemu.VSockConfig{GuestCID: 5}}}, func(event interface{}) error { return nil }, "comp2"), - }, - } - - tests := []struct { - name string - address string - want string - wantErr bool - }{ - {"Valid address", "vm(3)", "comp1", false}, - {"Invalid address", "invalid", "", true}, - {"Non-existent CID", "vm(10)", "", true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ms.computationIDFromAddress(tt.address) - if tt.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - assert.Equal(t, tt.want, got) - } - }) - } -} - -func TestReportBrokenConnection(t *testing.T) { - ms := &managerService{ - eventsChan: make(chan *ClientStreamMessage, 1), - vms: map[string]vm.VM{ - "comp1": qemu.NewVM(qemu.VMInfo{Config: qemu.Config{VSockConfig: qemu.VSockConfig{GuestCID: 3}}}, func(event interface{}) error { return nil }, "comp1"), - }, - } - - ms.reportBrokenConnection("comp1") - - select { - case msg := <-ms.eventsChan: - assert.Equal(t, "comp1", msg.GetAgentEvent().ComputationId) - assert.Equal(t, manager.Disconnected.String(), msg.GetAgentEvent().Status) - assert.Equal(t, "manager", msg.GetAgentEvent().Originator) - default: - t.Error("Expected message in eventsChan, but none received") - } -} diff --git a/manager/api/grpc/client.go b/manager/api/grpc/client.go deleted file mode 100644 index 389ffca9..00000000 --- a/manager/api/grpc/client.go +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package grpc - -import ( - "context" - "log/slog" - "sync" - "time" - - "github.com/absmach/magistrala/pkg/errors" - "github.com/ultravioletrs/cocos/manager" - "github.com/ultravioletrs/cocos/manager/qemu" - "golang.org/x/sync/errgroup" - "google.golang.org/protobuf/proto" -) - -var ( - errTerminationFromServer = errors.New("server requested client termination") - errCorruptedManifest = errors.New("received manifest may be corrupted") - sendTimeout = 5 * time.Second -) - -type ManagerClient struct { - stream manager.ManagerService_ProcessClient - svc manager.Service - messageQueue chan *manager.ClientStreamMessage - logger *slog.Logger - runReqManager *runRequestManager -} - -// NewClient returns new gRPC client instance. -func NewClient(stream manager.ManagerService_ProcessClient, svc manager.Service, messageQueue chan *manager.ClientStreamMessage, logger *slog.Logger) ManagerClient { - return ManagerClient{ - stream: stream, - svc: svc, - messageQueue: messageQueue, - logger: logger, - runReqManager: newRunRequestManager(), - } -} - -func (client ManagerClient) Process(ctx context.Context, cancel context.CancelFunc) error { - eg, ctx := errgroup.WithContext(ctx) - - eg.Go(func() error { - return client.handleIncomingMessages(ctx) - }) - - eg.Go(func() error { - return client.handleOutgoingMessages(ctx) - }) - - return eg.Wait() -} - -func (client ManagerClient) handleIncomingMessages(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - req, err := client.stream.Recv() - if err != nil { - return err - } - if err := client.processIncomingMessage(ctx, req); err != nil { - return err - } - } - } -} - -func (client ManagerClient) processIncomingMessage(ctx context.Context, req *manager.ServerStreamMessage) error { - switch mes := req.Message.(type) { - case *manager.ServerStreamMessage_RunReqChunks: - return client.handleRunReqChunks(ctx, mes) - case *manager.ServerStreamMessage_TerminateReq: - return client.handleTerminateReq(mes) - case *manager.ServerStreamMessage_StopComputation: - go client.handleStopComputation(ctx, mes) - case *manager.ServerStreamMessage_AttestationPolicyReq: - go client.handleAttestationPolicyReq(ctx, mes) - case *manager.ServerStreamMessage_SvmInfoReq: - go client.handleSVMInfoReq(ctx, mes) - default: - return errors.New("unknown message type") - } - return nil -} - -func (client *ManagerClient) handleRunReqChunks(ctx context.Context, mes *manager.ServerStreamMessage_RunReqChunks) error { - buffer, complete := client.runReqManager.addChunk(mes.RunReqChunks.Id, mes.RunReqChunks.Data, mes.RunReqChunks.IsLast) - - if complete { - var runReq manager.ComputationRunReq - if err := proto.Unmarshal(buffer, &runReq); err != nil { - return errors.Wrap(err, errCorruptedManifest) - } - - go client.executeRun(ctx, &runReq) - } - - return nil -} - -func (client ManagerClient) executeRun(ctx context.Context, runReq *manager.ComputationRunReq) { - port, err := client.svc.Run(ctx, runReq) - if err != nil { - client.logger.Warn(err.Error()) - return - } - runRes := &manager.ClientStreamMessage_RunRes{ - RunRes: &manager.RunResponse{ - AgentPort: port, - ComputationId: runReq.Id, - }, - } - client.sendMessage(&manager.ClientStreamMessage{Message: runRes}) -} - -func (client ManagerClient) handleTerminateReq(mes *manager.ServerStreamMessage_TerminateReq) error { - return errors.Wrap(errTerminationFromServer, errors.New(mes.TerminateReq.Message)) -} - -func (client ManagerClient) handleStopComputation(ctx context.Context, mes *manager.ServerStreamMessage_StopComputation) { - msg := &manager.ClientStreamMessage_StopComputationRes{ - StopComputationRes: &manager.StopComputationResponse{ - ComputationId: mes.StopComputation.ComputationId, - }, - } - if err := client.svc.Stop(ctx, mes.StopComputation.ComputationId); err != nil { - msg.StopComputationRes.Message = err.Error() - } - client.sendMessage(&manager.ClientStreamMessage{Message: msg}) -} - -func (client ManagerClient) handleAttestationPolicyReq(ctx context.Context, mes *manager.ServerStreamMessage_AttestationPolicyReq) { - res, err := client.svc.FetchAttestationPolicy(ctx, mes.AttestationPolicyReq.Id) - if err != nil { - client.logger.Warn(err.Error()) - return - } - info := &manager.ClientStreamMessage_AttestationPolicy{ - AttestationPolicy: &manager.AttestationPolicy{ - Info: res, - Id: mes.AttestationPolicyReq.Id, - }, - } - client.sendMessage(&manager.ClientStreamMessage{Message: info}) -} - -func (client ManagerClient) handleSVMInfoReq(ctx context.Context, mes *manager.ServerStreamMessage_SvmInfoReq) { - ovmfVersion, cpuNum, cpuType, eosVersion := client.svc.ReturnSVMInfo(ctx) - info := &manager.ClientStreamMessage_SvmInfo{ - SvmInfo: &manager.SVMInfo{ - OvmfVersion: ovmfVersion, - CpuNum: int32(cpuNum), - CpuType: cpuType, - KernelCmd: qemu.KernelCommandLine, - EosVersion: eosVersion, - Id: mes.SvmInfoReq.Id, - }, - } - client.sendMessage(&manager.ClientStreamMessage{Message: info}) -} - -func (client ManagerClient) handleOutgoingMessages(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - case mes := <-client.messageQueue: - if err := client.stream.Send(mes); err != nil { - return err - } - } - } -} - -func (client ManagerClient) sendMessage(mes *manager.ClientStreamMessage) { - ctx, cancel := context.WithTimeout(context.Background(), sendTimeout) - defer cancel() - - select { - case client.messageQueue <- mes: - case <-ctx.Done(): - client.logger.Warn("Failed to send message: timeout exceeded") - } -} - -type runRequestManager struct { - requests map[string]*runRequest - mu sync.Mutex -} - -type runRequest struct { - buffer []byte - lastChunk time.Time - timer *time.Timer -} - -func newRunRequestManager() *runRequestManager { - return &runRequestManager{ - requests: make(map[string]*runRequest), - } -} - -func (m *runRequestManager) addChunk(id string, chunk []byte, isLast bool) ([]byte, bool) { - m.mu.Lock() - defer m.mu.Unlock() - - req, exists := m.requests[id] - if !exists { - req = &runRequest{ - buffer: make([]byte, 0), - lastChunk: time.Now(), - timer: time.AfterFunc(runReqTimeout, func() { m.timeoutRequest(id) }), - } - m.requests[id] = req - } - - req.buffer = append(req.buffer, chunk...) - req.lastChunk = time.Now() - req.timer.Reset(runReqTimeout) - - if isLast { - delete(m.requests, id) - req.timer.Stop() - return req.buffer, true - } - - return nil, false -} - -func (m *runRequestManager) timeoutRequest(id string) { - m.mu.Lock() - defer m.mu.Unlock() - - delete(m.requests, id) - // Log timeout or handle it as needed -} diff --git a/manager/api/grpc/client_test.go b/manager/api/grpc/client_test.go deleted file mode 100644 index f8dc61d0..00000000 --- a/manager/api/grpc/client_test.go +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package grpc - -import ( - "context" - "testing" - "time" - - mglog "github.com/absmach/magistrala/logger" - "github.com/absmach/magistrala/pkg/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/ultravioletrs/cocos/manager" - "github.com/ultravioletrs/cocos/manager/mocks" - "github.com/ultravioletrs/cocos/manager/qemu" - "google.golang.org/grpc" - "google.golang.org/protobuf/proto" -) - -type mockStream struct { - mock.Mock - grpc.ClientStream -} - -func (m *mockStream) Recv() (*manager.ServerStreamMessage, error) { - args := m.Called() - return args.Get(0).(*manager.ServerStreamMessage), args.Error(1) -} - -func (m *mockStream) Send(msg *manager.ClientStreamMessage) error { - args := m.Called(msg) - return args.Error(0) -} - -func TestManagerClient_Process1(t *testing.T) { - tests := []struct { - name string - setupMocks func(mockStream *mockStream, mockSvc *mocks.Service) - expectError bool - errorMsg string - }{ - { - name: "Stop computation", - setupMocks: func(mockStream *mockStream, mockSvc *mocks.Service) { - mockStream.On("Recv").Return(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_StopComputation{ - StopComputation: &manager.StopComputation{}, - }, - }, nil) - mockStream.On("Send", mock.Anything).Return(nil) - mockSvc.On("Stop", mock.Anything, mock.Anything).Return(nil) - }, - expectError: true, - errorMsg: "context deadline exceeded", - }, - { - name: "Terminate request", - setupMocks: func(mockStream *mockStream, mockSvc *mocks.Service) { - mockStream.On("Recv").Return(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_TerminateReq{ - TerminateReq: &manager.Terminate{}, - }, - }, nil) - }, - expectError: true, - errorMsg: errTerminationFromServer.Error(), - }, - { - name: "Attestation Policy request", - setupMocks: func(mockStream *mockStream, mockSvc *mocks.Service) { - mockStream.On("Recv").Return(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_AttestationPolicyReq{ - AttestationPolicyReq: &manager.AttestationPolicyReq{}, - }, - }, nil) - mockStream.On("Send", mock.Anything).Return(nil).Once() - mockSvc.On("FetchAttestationPolicy", mock.Anything, mock.Anything).Return(nil, assert.AnError) - }, - expectError: true, - }, - { - name: "Run request chunks", - setupMocks: func(mockStream *mockStream, mockSvc *mocks.Service) { - mockStream.On("Recv").Return(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_RunReqChunks{ - RunReqChunks: &manager.RunReqChunks{}, - }, - }, nil) - mockStream.On("Send", mock.Anything).Return(nil).Once() - mockSvc.On("Run", mock.Anything, mock.Anything).Return("", assert.AnError).Once() - }, - expectError: true, - }, - { - name: "Receive error", - setupMocks: func(mockStream *mockStream, mockSvc *mocks.Service) { - mockStream.On("Recv").Return(&manager.ServerStreamMessage{}, assert.AnError) - }, - expectError: true, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - mockStream := new(mockStream) - mockSvc := new(mocks.Service) - messageQueue := make(chan *manager.ClientStreamMessage, 10) - logger := mglog.NewMock() - - client := NewClient(mockStream, mockSvc, messageQueue, logger) - - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) - defer cancel() - - tc.setupMocks(mockStream, mockSvc) - - err := client.Process(ctx, cancel) - - if tc.expectError { - assert.Error(t, err) - if tc.errorMsg != "" { - assert.Contains(t, err.Error(), tc.errorMsg) - } - } else { - assert.NoError(t, err) - } - }) - } -} - -func TestManagerClient_handleRunReqChunks(t *testing.T) { - mockStream := new(mockStream) - mockSvc := new(mocks.Service) - messageQueue := make(chan *manager.ClientStreamMessage, 10) - logger := mglog.NewMock() - - client := NewClient(mockStream, mockSvc, messageQueue, logger) - - runReq := &manager.ComputationRunReq{ - Id: "test-id", - } - runReqBytes, _ := proto.Marshal(runReq) - - chunk1 := &manager.ServerStreamMessage_RunReqChunks{ - RunReqChunks: &manager.RunReqChunks{ - Id: "chunk-1", - Data: runReqBytes[:len(runReqBytes)/2], - IsLast: false, - }, - } - chunk2 := &manager.ServerStreamMessage_RunReqChunks{ - RunReqChunks: &manager.RunReqChunks{ - Id: "chunk-1", - Data: runReqBytes[len(runReqBytes)/2:], - IsLast: true, - }, - } - - mockSvc.On("Run", mock.Anything, mock.AnythingOfType("*manager.ComputationRunReq")).Return("8080", nil) - - err := client.handleRunReqChunks(context.Background(), chunk1) - assert.NoError(t, err) - - err = client.handleRunReqChunks(context.Background(), chunk2) - assert.NoError(t, err) - - // Wait for the goroutine to finish - time.Sleep(50 * time.Millisecond) - - mockSvc.AssertExpectations(t) - assert.Len(t, messageQueue, 1) - - msg := <-messageQueue - runRes, ok := msg.Message.(*manager.ClientStreamMessage_RunRes) - assert.True(t, ok) - assert.Equal(t, "8080", runRes.RunRes.AgentPort) - assert.Equal(t, "test-id", runRes.RunRes.ComputationId) -} - -func TestManagerClient_handleTerminateReq(t *testing.T) { - client := ManagerClient{} - - terminateReq := &manager.ServerStreamMessage_TerminateReq{ - TerminateReq: &manager.Terminate{ - Message: "Test termination", - }, - } - - err := client.handleTerminateReq(terminateReq) - assert.Error(t, err) - assert.Contains(t, err.Error(), "Test termination") - assert.True(t, errors.Contains(err, errTerminationFromServer)) -} - -func TestManagerClient_handleStopComputation(t *testing.T) { - mockStream := new(mockStream) - mockSvc := new(mocks.Service) - messageQueue := make(chan *manager.ClientStreamMessage, 10) - logger := mglog.NewMock() - - client := NewClient(mockStream, mockSvc, messageQueue, logger) - - stopReq := &manager.ServerStreamMessage_StopComputation{ - StopComputation: &manager.StopComputation{ - ComputationId: "test-comp-id", - }, - } - - mockSvc.On("Stop", mock.Anything, "test-comp-id").Return(nil) - - client.handleStopComputation(context.Background(), stopReq) - - // Wait for the goroutine to finish - time.Sleep(50 * time.Millisecond) - - mockSvc.AssertExpectations(t) - assert.Len(t, messageQueue, 1) - - msg := <-messageQueue - stopRes, ok := msg.Message.(*manager.ClientStreamMessage_StopComputationRes) - assert.True(t, ok) - assert.Equal(t, "test-comp-id", stopRes.StopComputationRes.ComputationId) - assert.Empty(t, stopRes.StopComputationRes.Message) -} - -func TestManagerClient_handleAttestationPolicyReq(t *testing.T) { - t.Run("success", func(t *testing.T) { - mockStream := new(mockStream) - mockSvc := new(mocks.Service) - messageQueue := make(chan *manager.ClientStreamMessage, 10) - logger := mglog.NewMock() - - client := NewClient(mockStream, mockSvc, messageQueue, logger) - - infoReq := &manager.ServerStreamMessage_AttestationPolicyReq{ - AttestationPolicyReq: &manager.AttestationPolicyReq{ - Id: "test-info-id", - }, - } - - mockSvc.On("FetchAttestationPolicy", context.Background(), infoReq.AttestationPolicyReq.Id).Return([]byte("test-attestation-policy"), nil) - - client.handleAttestationPolicyReq(context.Background(), infoReq) - - // Wait for the goroutine to finish - time.Sleep(50 * time.Millisecond) - - mockSvc.AssertExpectations(t) - assert.Len(t, messageQueue, 1) - - msg := <-messageQueue - infoRes, ok := msg.Message.(*manager.ClientStreamMessage_AttestationPolicy) - assert.True(t, ok) - assert.Equal(t, "test-info-id", infoRes.AttestationPolicy.Id) - assert.Equal(t, []byte("test-attestation-policy"), infoRes.AttestationPolicy.Info) - }) - t.Run("error", func(t *testing.T) { - mockStream := new(mockStream) - mockSvc := new(mocks.Service) - messageQueue := make(chan *manager.ClientStreamMessage, 10) - logger := mglog.NewMock() - - client := NewClient(mockStream, mockSvc, messageQueue, logger) - - infoReq := &manager.ServerStreamMessage_AttestationPolicyReq{ - AttestationPolicyReq: &manager.AttestationPolicyReq{ - Id: "test-info-id", - }, - } - - mockSvc.On("FetchAttestationPolicy", context.Background(), infoReq.AttestationPolicyReq.Id).Return(nil, assert.AnError) - - client.handleAttestationPolicyReq(context.Background(), infoReq) - - time.Sleep(50 * time.Millisecond) - - mockSvc.AssertExpectations(t) - assert.Len(t, messageQueue, 0) - }) -} - -func TestManagerClient_handleSVMInfoReq(t *testing.T) { - mockStream := new(mockStream) - mockSvc := new(mocks.Service) - messageQueue := make(chan *manager.ClientStreamMessage, 10) - logger := mglog.NewMock() - - client := NewClient(mockStream, mockSvc, messageQueue, logger) - - mockSvc.On("ReturnSVMInfo", context.Background()).Return("edk2-stable202408", 4, "EPYC", "") - - client.handleSVMInfoReq(context.Background(), &manager.ServerStreamMessage_SvmInfoReq{SvmInfoReq: &manager.SVMInfoReq{Id: "test-svm-info-id"}}) - - // Wait for the goroutine to finish - time.Sleep(50 * time.Millisecond) - - mockSvc.AssertExpectations(t) - assert.Len(t, messageQueue, 1) - - msg := <-messageQueue - infoRes, ok := msg.Message.(*manager.ClientStreamMessage_SvmInfo) - assert.True(t, ok) - assert.Equal(t, "edk2-stable202408", infoRes.SvmInfo.OvmfVersion) - assert.Equal(t, int32(4), infoRes.SvmInfo.CpuNum) - assert.Equal(t, "EPYC", infoRes.SvmInfo.CpuType) - assert.Equal(t, "", infoRes.SvmInfo.EosVersion) - assert.Equal(t, qemu.KernelCommandLine, infoRes.SvmInfo.KernelCmd) -} - -func TestManagerClient_timeoutRequest(t *testing.T) { - rm := newRunRequestManager() - rm.requests["test-id"] = &runRequest{ - timer: time.NewTimer(100 * time.Millisecond), - buffer: []byte("test-data"), - lastChunk: time.Now(), - } - - rm.timeoutRequest("test-id") - - assert.Len(t, rm.requests, 0) -} diff --git a/manager/api/grpc/server.go b/manager/api/grpc/server.go index 6a896d13..83e7ab65 100644 --- a/manager/api/grpc/server.go +++ b/manager/api/grpc/server.go @@ -3,17 +3,11 @@ package grpc import ( - "bytes" "context" "errors" - "io" - "time" "github.com/ultravioletrs/cocos/manager" - "golang.org/x/sync/errgroup" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/peer" - "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/emptypb" ) var ( @@ -21,113 +15,58 @@ var ( ErrUnexpectedMsg = errors.New("unknown message type") ) -const ( - bufferSize = 1024 * 1024 // 1 MB - runReqTimeout = 30 * time.Second -) - -type SendFunc func(*manager.ServerStreamMessage) error - type grpcServer struct { manager.UnimplementedManagerServiceServer - incoming chan *manager.ClientStreamMessage - svc Service -} - -type Service interface { - Run(ctx context.Context, ipAddress string, sendMessage SendFunc, authInfo credentials.AuthInfo) + svc manager.Service } // NewServer returns new AuthServiceServer instance. -func NewServer(incoming chan *manager.ClientStreamMessage, svc Service) manager.ManagerServiceServer { +func NewServer(svc manager.Service) manager.ManagerServiceServer { return &grpcServer{ - incoming: incoming, - svc: svc, + svc: svc, } } -func (s *grpcServer) Process(stream manager.ManagerService_ProcessServer) error { - client, ok := peer.FromContext(stream.Context()) - if !ok { - return errors.New("failed to get peer info") +func (s *grpcServer) CreateVm(ctx context.Context, _ *emptypb.Empty) (*manager.CreateRes, error) { + port, id, err := s.svc.CreateVM(ctx) + if err != nil { + return nil, err } - eg, ctx := errgroup.WithContext(stream.Context()) - - eg.Go(func() error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: - req, err := stream.Recv() - if err != nil { - return err - } - s.incoming <- req - } - } - }) - - eg.Go(func() error { - sendMessage := func(msg *manager.ServerStreamMessage) error { - select { - case <-ctx.Done(): - return ctx.Err() - default: - switch m := msg.Message.(type) { - case *manager.ServerStreamMessage_RunReq: - return s.sendRunReqInChunks(stream, m.RunReq) - default: - return stream.Send(msg) - } - } - } - - s.svc.Run(ctx, client.Addr.String(), sendMessage, client.AuthInfo) - return nil - }) - - return eg.Wait() + return &manager.CreateRes{ + ForwardedPort: port, + SvmId: id, + }, nil } -func (s *grpcServer) sendRunReqInChunks(stream manager.ManagerService_ProcessServer, runReq *manager.ComputationRunReq) error { - data, err := proto.Marshal(runReq) - if err != nil { - return err +func (s *grpcServer) RemoveVm(ctx context.Context, req *manager.RemoveReq) (*emptypb.Empty, error) { + if err := s.svc.RemoveVM(ctx, req.SvmId); err != nil { + return nil, err } - dataBuffer := bytes.NewBuffer(data) - buf := make([]byte, bufferSize) - - for { - n, err := dataBuffer.Read(buf) - isLast := false - - if err == io.EOF { - isLast = true - } else if err != nil { - return err - } + return &emptypb.Empty{}, nil +} - chunk := &manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_RunReqChunks{ - RunReqChunks: &manager.RunReqChunks{ - Id: runReq.Id, - Data: buf[:n], - IsLast: isLast, - }, - }, - } +func (s *grpcServer) SVMInfo(ctx context.Context, req *manager.SVMInfoReq) (*manager.SVMInfoRes, error) { + ovmf, cpunum, cputype, eosversion := s.svc.ReturnSVMInfo(ctx) - if err := stream.Send(chunk); err != nil { - return err - } + return &manager.SVMInfoRes{ + OvmfVersion: ovmf, + CpuNum: int32(cpunum), + CpuType: cputype, + EosVersion: eosversion, + Id: req.Id, + }, nil +} - if isLast { - break - } +func (s *grpcServer) AttestationPolicy(ctx context.Context, req *manager.AttestationPolicyReq) (*manager.AttestationPolicyRes, error) { + policy, err := s.svc.FetchAttestationPolicy(ctx, req.Id) + if err != nil { + return nil, err } - return nil + return &manager.AttestationPolicyRes{ + Info: policy, + Id: req.Id, + }, nil } diff --git a/manager/api/grpc/server_test.go b/manager/api/grpc/server_test.go deleted file mode 100644 index f4b9778a..00000000 --- a/manager/api/grpc/server_test.go +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package grpc - -import ( - "context" - "testing" - "time" - - "github.com/absmach/magistrala/pkg/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/ultravioletrs/cocos/manager" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/peer" -) - -type mockServerStream struct { - mock.Mock - manager.ManagerService_ProcessServer -} - -func (m *mockServerStream) Send(msg *manager.ServerStreamMessage) error { - args := m.Called(msg) - return args.Error(0) -} - -func (m *mockServerStream) Recv() (*manager.ClientStreamMessage, error) { - args := m.Called() - return args.Get(0).(*manager.ClientStreamMessage), args.Error(1) -} - -func (m *mockServerStream) Context() context.Context { - args := m.Called() - return args.Get(0).(context.Context) -} - -type mockService struct { - mock.Mock -} - -func (m *mockService) Run(ctx context.Context, ipAddress string, sendMessage SendFunc, authInfo credentials.AuthInfo) { - m.Called(ctx, ipAddress, sendMessage, authInfo) -} - -func TestNewServer(t *testing.T) { - incoming := make(chan *manager.ClientStreamMessage) - mockSvc := new(mockService) - - server := NewServer(incoming, mockSvc) - - assert.NotNil(t, server) - assert.IsType(t, &grpcServer{}, server) -} - -func TestGrpcServer_Process(t *testing.T) { - tests := []struct { - name string - recvReturn *manager.ClientStreamMessage - recvError error - expectedError string - }{ - { - name: "Process with context deadline exceeded", - recvReturn: &manager.ClientStreamMessage{}, - recvError: nil, - expectedError: "context deadline exceeded", - }, - { - name: "Process with Recv error", - recvReturn: &manager.ClientStreamMessage{}, - recvError: errors.New("recv error"), - expectedError: "recv error", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - incoming := make(chan *manager.ClientStreamMessage, 1) - mockSvc := new(mockService) - server := NewServer(incoming, mockSvc).(*grpcServer) - - mockStream := new(mockServerStream) - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) - defer cancel() - - mockStream.On("Context").Return(peer.NewContext(ctx, &peer.Peer{ - Addr: mockAddr{}, - AuthInfo: mockAuthInfo{}, - })) - - if tt.recvError == nil { - go func() { - for mes := range incoming { - assert.NotNil(t, mes) - } - }() - } - - mockStream.On("Recv").Return(tt.recvReturn, tt.recvError) - mockSvc.On("Run", mock.Anything, "test", mock.Anything, mock.AnythingOfType("mockAuthInfo")).Return() - - err := server.Process(mockStream) - - assert.Error(t, err) - assert.Contains(t, err.Error(), tt.expectedError) - mockStream.AssertExpectations(t) - mockSvc.AssertExpectations(t) - }) - } -} - -func TestGrpcServer_sendRunReqInChunks(t *testing.T) { - incoming := make(chan *manager.ClientStreamMessage) - mockSvc := new(mockService) - server := NewServer(incoming, mockSvc).(*grpcServer) - - mockStream := new(mockServerStream) - - runReq := &manager.ComputationRunReq{ - Id: "test-id", - } - - largePayload := make([]byte, bufferSize*2) - for i := range largePayload { - largePayload[i] = byte(i % 256) - } - runReq.Algorithm = &manager.Algorithm{} - runReq.Algorithm.UserKey = largePayload - - mockStream.On("Send", mock.AnythingOfType("*manager.ServerStreamMessage")).Return(nil).Times(4) - - err := server.sendRunReqInChunks(mockStream, runReq) - - assert.NoError(t, err) - mockStream.AssertExpectations(t) - - calls := mockStream.Calls - assert.Equal(t, 4, len(calls)) - - for i, call := range calls { - msg := call.Arguments[0].(*manager.ServerStreamMessage) - chunk := msg.GetRunReqChunks() - - assert.NotNil(t, chunk) - assert.Equal(t, "test-id", chunk.Id) - - if i < 3 { - assert.False(t, chunk.IsLast) - } else { - assert.Equal(t, 0, len(chunk.Data)) - assert.True(t, chunk.IsLast) - } - } -} - -type mockAddr struct{} - -func (mockAddr) Network() string { return "test network" } -func (mockAddr) String() string { return "test" } - -type mockAuthInfo struct{} - -func (mockAuthInfo) AuthType() string { return "test auth" } - -func TestGrpcServer_ProcessWithMockService(t *testing.T) { - tests := []struct { - name string - setupMockFn func(*mockService, *mockServerStream) - }{ - { - name: "Run Request Test", - setupMockFn: func(mockSvc *mockService, mockStream *mockServerStream) { - mockSvc.On("Run", mock.Anything, "test", mock.Anything, mock.AnythingOfType("mockAuthInfo")). - Run(func(args mock.Arguments) { - sendFunc := args.Get(2).(SendFunc) - runReq := &manager.ComputationRunReq{Id: "test-run-id"} - err := sendFunc(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_RunReq{ - RunReq: runReq, - }, - }) - assert.NoError(t, err) - }). - Return() - - mockStream.On("Send", mock.MatchedBy(func(msg *manager.ServerStreamMessage) bool { - chunks := msg.GetRunReqChunks() - return chunks != nil && chunks.Id == "test-run-id" - })).Return(nil) - }, - }, - { - name: "Terminate Request Test", - setupMockFn: func(mockSvc *mockService, mockStream *mockServerStream) { - mockSvc.On("Run", mock.Anything, "test", mock.Anything, mock.AnythingOfType("mockAuthInfo")). - Run(func(args mock.Arguments) { - sendFunc := args.Get(2).(SendFunc) - err := sendFunc(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_TerminateReq{ - TerminateReq: &manager.Terminate{}, - }, - }) - assert.NoError(t, err) - }).Return() - - mockStream.On("Send", mock.AnythingOfType("*manager.ServerStreamMessage")).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - incoming := make(chan *manager.ClientStreamMessage, 10) - mockSvc := new(mockService) - server := NewServer(incoming, mockSvc).(*grpcServer) - - go func() { - for mes := range incoming { - assert.NotNil(t, mes) - } - }() - - mockStream := new(mockServerStream) - ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) - defer cancel() - - peerCtx := peer.NewContext(ctx, &peer.Peer{ - Addr: mockAddr{}, - AuthInfo: mockAuthInfo{}, - }) - - mockStream.On("Context").Return(peerCtx) - mockStream.On("Recv").Return(&manager.ClientStreamMessage{}, nil).Maybe() - - tt.setupMockFn(mockSvc, mockStream) - - go func() { - time.Sleep(150 * time.Millisecond) - cancel() - }() - - err := server.Process(mockStream) - - assert.Error(t, err) - assert.Contains(t, err.Error(), "context canceled") - mockStream.AssertExpectations(t) - mockSvc.AssertExpectations(t) - }) - } -} - -func TestGrpcServer_sendRunReqInChunksError(t *testing.T) { - incoming := make(chan *manager.ClientStreamMessage) - mockSvc := new(mockService) - server := NewServer(incoming, mockSvc).(*grpcServer) - - mockStream := new(mockServerStream) - - runReq := &manager.ComputationRunReq{ - Id: "test-id", - } - - // Simulate an error when sending - mockStream.On("Send", mock.AnythingOfType("*manager.ServerStreamMessage")).Return(errors.New("send error")).Once() - - err := server.sendRunReqInChunks(mockStream, runReq) - - assert.Error(t, err) - assert.Contains(t, err.Error(), "send error") - mockStream.AssertExpectations(t) -} - -func TestGrpcServer_ProcessMissingPeerInfo(t *testing.T) { - incoming := make(chan *manager.ClientStreamMessage) - mockSvc := new(mockService) - server := NewServer(incoming, mockSvc).(*grpcServer) - - mockStream := new(mockServerStream) - ctx := context.Background() - - // Return a context without peer info - mockStream.On("Context").Return(ctx) - - err := server.Process(mockStream) - - assert.Error(t, err) - assert.Contains(t, err.Error(), "failed to get peer info") - mockStream.AssertExpectations(t) -} diff --git a/manager/api/logging.go b/manager/api/logging.go index 7f3a0c42..e352a927 100644 --- a/manager/api/logging.go +++ b/manager/api/logging.go @@ -27,9 +27,9 @@ func LoggingMiddleware(svc manager.Service, logger *slog.Logger) manager.Service return &loggingMiddleware{logger, svc} } -func (lm *loggingMiddleware) Run(ctx context.Context, mc *manager.ComputationRunReq) (agentAddr string, err error) { +func (lm *loggingMiddleware) CreateVM(ctx context.Context) (agentAddr string, id string, err error) { defer func(begin time.Time) { - message := fmt.Sprintf("Method Run for computation took %s to complete", time.Since(begin)) + message := fmt.Sprintf("Method CreateVM for id %s on port %s took %s to complete", id, agentAddr, time.Since(begin)) if err != nil { lm.logger.Warn(fmt.Sprintf("%s with error: %s.", message, err)) return @@ -37,12 +37,12 @@ func (lm *loggingMiddleware) Run(ctx context.Context, mc *manager.ComputationRun lm.logger.Info(message) }(time.Now()) - return lm.svc.Run(ctx, mc) + return lm.svc.CreateVM(ctx) } -func (lm *loggingMiddleware) Stop(ctx context.Context, computationID string) (err error) { +func (lm *loggingMiddleware) RemoveVM(ctx context.Context, id string) (err error) { defer func(begin time.Time) { - message := fmt.Sprintf("Method Stop for computation took %s to complete", time.Since(begin)) + message := fmt.Sprintf("Method RemoveVM for vm %s took %s to complete", id, time.Since(begin)) if err != nil { lm.logger.Warn(fmt.Sprintf("%s with error: %s.", message, err)) return @@ -50,7 +50,7 @@ func (lm *loggingMiddleware) Stop(ctx context.Context, computationID string) (er lm.logger.Info(message) }(time.Now()) - return lm.svc.Stop(ctx, computationID) + return lm.svc.RemoveVM(ctx, id) } func (lm *loggingMiddleware) FetchAttestationPolicy(ctx context.Context, cmpId string) (body []byte, err error) { @@ -67,10 +67,6 @@ func (lm *loggingMiddleware) FetchAttestationPolicy(ctx context.Context, cmpId s return lm.svc.FetchAttestationPolicy(ctx, cmpId) } -func (lm *loggingMiddleware) ReportBrokenConnection(addr string) { - lm.svc.ReportBrokenConnection(addr) -} - func (lm *loggingMiddleware) ReturnSVMInfo(ctx context.Context) (string, int, string, string) { defer func(begin time.Time) { message := fmt.Sprintf("Method ReturnSVMInfo for computation took %s to complete", time.Since(begin)) diff --git a/manager/api/metrics.go b/manager/api/metrics.go index 64b5dff9..c521efc0 100644 --- a/manager/api/metrics.go +++ b/manager/api/metrics.go @@ -32,22 +32,22 @@ func MetricsMiddleware(svc manager.Service, counter metrics.Counter, latency met } } -func (ms *metricsMiddleware) Run(ctx context.Context, mc *manager.ComputationRunReq) (string, error) { +func (ms *metricsMiddleware) CreateVM(ctx context.Context) (string, string, error) { defer func(begin time.Time) { ms.counter.With("method", "Run").Add(1) ms.latency.With("method", "Run").Observe(time.Since(begin).Seconds()) }(time.Now()) - return ms.svc.Run(ctx, mc) + return ms.svc.CreateVM(ctx) } -func (ms *metricsMiddleware) Stop(ctx context.Context, computationID string) error { +func (ms *metricsMiddleware) RemoveVM(ctx context.Context, computationID string) error { defer func(begin time.Time) { ms.counter.With("method", "Stop").Add(1) ms.latency.With("method", "Stop").Observe(time.Since(begin).Seconds()) }(time.Now()) - return ms.svc.Stop(ctx, computationID) + return ms.svc.RemoveVM(ctx, computationID) } func (ms *metricsMiddleware) FetchAttestationPolicy(ctx context.Context, cmpId string) ([]byte, error) { @@ -59,10 +59,6 @@ func (ms *metricsMiddleware) FetchAttestationPolicy(ctx context.Context, cmpId s return ms.svc.FetchAttestationPolicy(ctx, cmpId) } -func (ms *metricsMiddleware) ReportBrokenConnection(addr string) { - ms.svc.ReportBrokenConnection(addr) -} - func (ms *metricsMiddleware) ReturnSVMInfo(ctx context.Context) (string, int, string, string) { defer func(begin time.Time) { ms.counter.With("method", "ReturnSVMInfo").Add(1) diff --git a/manager/events/events.go b/manager/events/events.go deleted file mode 100644 index a87a3329..00000000 --- a/manager/events/events.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package events - -import "context" - -type Listener interface { - Listen(ctx context.Context) -} diff --git a/manager/events/vsock.go b/manager/events/vsock.go deleted file mode 100644 index 24e9c170..00000000 --- a/manager/events/vsock.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package events - -import ( - "context" - "log/slog" - "net" - - "github.com/mdlayher/vsock" - agentevents "github.com/ultravioletrs/cocos/agent/events" - internalvsock "github.com/ultravioletrs/cocos/internal/vsock" - "github.com/ultravioletrs/cocos/manager" - "google.golang.org/protobuf/proto" -) - -const ManagerVsockPort = 9997 - -type ReportBrokenConnectionFunc func(address string) - -type events struct { - reportBrokenConnection ReportBrokenConnectionFunc - lis net.Listener - logger *slog.Logger - eventsChan chan *manager.ClientStreamMessage -} - -func New(logger *slog.Logger, reportBrokenConnection ReportBrokenConnectionFunc, eventsChan chan *manager.ClientStreamMessage) (Listener, error) { - l, err := vsock.Listen(ManagerVsockPort, nil) - if err != nil { - return nil, err - } - return &events{ - lis: l, - reportBrokenConnection: reportBrokenConnection, - logger: logger, - eventsChan: eventsChan, - }, nil -} - -func (e *events) Listen(ctx context.Context) { - for { - select { - case <-ctx.Done(): - e.logger.Info("Listener shutting down") - return - default: - conn, err := e.lis.Accept() - if err != nil { - e.logger.Warn(err.Error()) - continue - } - - go e.handleConnection(conn) - } - } -} - -func (e *events) handleConnection(conn net.Conn) { - defer conn.Close() - - ackReader := internalvsock.NewAckReader(conn) - - for { - var message agentevents.EventsLogs - data, err := ackReader.Read() - if err != nil { - go e.reportBrokenConnection(conn.RemoteAddr().String()) - e.logger.Warn(err.Error()) - return - } - - if err := proto.Unmarshal(data, &message); err != nil { - e.logger.Warn(err.Error()) - continue - } - - var mes manager.ClientStreamMessage - - args := []any{} - - switch message.Message.(type) { - case *agentevents.EventsLogs_AgentEvent: - args = append(args, slog.Group("agent-event", - slog.String("event-type", message.GetAgentEvent().GetEventType()), - slog.String("computation-id", message.GetAgentEvent().GetComputationId()), - slog.String("status", message.GetAgentEvent().GetStatus()), - slog.String("originator", message.GetAgentEvent().GetOriginator()), - slog.String("timestamp", message.GetAgentEvent().GetTimestamp().String()), - slog.String("details", string(message.GetAgentEvent().GetDetails())))) - mes = manager.ClientStreamMessage{ - Message: &manager.ClientStreamMessage_AgentEvent{ - AgentEvent: &manager.AgentEvent{ - EventType: message.GetAgentEvent().GetEventType(), - ComputationId: message.GetAgentEvent().GetComputationId(), - Status: message.GetAgentEvent().GetStatus(), - Originator: message.GetAgentEvent().GetOriginator(), - Timestamp: message.GetAgentEvent().GetTimestamp(), - Details: message.GetAgentEvent().GetDetails(), - }, - }, - } - case *agentevents.EventsLogs_AgentLog: - args = append(args, slog.Group("agent-log", - slog.String("computation-id", message.GetAgentLog().GetComputationId()), - slog.String("level", message.GetAgentLog().GetLevel()), - slog.String("timestamp", message.GetAgentLog().GetTimestamp().String()), - slog.String("message", message.GetAgentLog().GetMessage()))) - mes = manager.ClientStreamMessage{ - Message: &manager.ClientStreamMessage_AgentLog{ - AgentLog: &manager.AgentLog{ - ComputationId: message.GetAgentLog().GetComputationId(), - Level: message.GetAgentLog().GetLevel(), - Timestamp: message.GetAgentLog().GetTimestamp(), - Message: message.GetAgentLog().GetMessage(), - }, - }, - } - } - - e.eventsChan <- &mes - - e.logger.Info("", args...) - } -} diff --git a/manager/events/vsock_test.go b/manager/events/vsock_test.go deleted file mode 100644 index dfb841e5..00000000 --- a/manager/events/vsock_test.go +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package events - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - "log/slog" - "net" - "os" - "testing" - "time" - - mglog "github.com/absmach/magistrala/logger" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/ultravioletrs/cocos/manager" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -type MockVsockListener struct { - mock.Mock -} - -func (m *MockVsockListener) Accept() (net.Conn, error) { - args := m.Called() - return args.Get(0).(net.Conn), args.Error(1) -} - -func (m *MockVsockListener) Close() error { - args := m.Called() - return args.Error(0) -} - -func (m *MockVsockListener) Addr() net.Addr { - args := m.Called() - return args.Get(0).(net.Addr) -} - -var _ net.Conn = (*MockConn)(nil) - -type MockConn struct { - mock.Mock -} - -func (m *MockConn) Read(b []byte) (n int, err error) { - args := m.Called(b) - return args.Int(0), args.Error(1) -} - -func (m *MockConn) Write(b []byte) (n int, err error) { - args := m.Called(b) - return args.Int(0), args.Error(1) -} - -func (m *MockConn) Close() error { - args := m.Called() - return args.Error(0) -} - -func (m *MockConn) LocalAddr() net.Addr { - args := m.Called() - return args.Get(0).(net.Addr) -} - -func (m *MockConn) RemoteAddr() net.Addr { - args := m.Called() - return args.Get(0).(net.Addr) -} - -func (m *MockConn) SetDeadline(t time.Time) error { - args := m.Called(t) - return args.Error(0) -} - -func (m *MockConn) SetReadDeadline(t time.Time) error { - args := m.Called(t) - return args.Error(0) -} - -func (m *MockConn) SetWriteDeadline(t time.Time) error { - args := m.Called(t) - return args.Error(0) -} - -func TestNew(t *testing.T) { - logger := &slog.Logger{} - reportBrokenConnection := func(address string) {} - eventsChan := make(chan *manager.ClientStreamMessage) - - e, err := New(logger, reportBrokenConnection, eventsChan) - - if vsockDeviceExists() { - assert.NoError(t, err) - - assert.NotNil(t, e) - assert.IsType(t, &events{}, e) - } else { - assert.Error(t, err) - } -} - -func TestListen(t *testing.T) { - mockListener := new(MockVsockListener) - mockConn := new(MockConn) - - e := &events{ - lis: mockListener, - logger: mglog.NewMock(), - } - - mockListener.On("Accept").Return(mockConn, fmt.Errorf("mock error")).Once() - mockListener.On("Accept").Return(mockConn, nil) - mockConn.On("Close").Return(nil) - mockConn.On("Read", mock.Anything).Return(0, nil) - - go e.Listen(context.Background()) - - time.Sleep(100 * time.Millisecond) - - mockListener.AssertExpectations(t) -} - -func TestListenContextDone(t *testing.T) { - mockListener := new(MockVsockListener) - mockConn := new(MockConn) - - e := &events{ - lis: mockListener, - logger: mglog.NewMock(), - } - - ctx, cancel := context.WithCancel(context.Background()) - cancel() - - mockListener.On("Accept").Return(mockConn, nil) - - e.Listen(ctx) - - time.Sleep(100 * time.Millisecond) -} - -func vsockDeviceExists() bool { - fs, err := os.Stat("/dev/vsock") - if err != nil { - return false - } - if fs.Mode()&os.ModeDevice == 0 { - return false - } - return true -} - -type MockConnWithBuffer struct { - mock.Mock - readBuf *bytes.Buffer - writeBuf *bytes.Buffer -} - -func NewMockConnWithBuffer() *MockConnWithBuffer { - return &MockConnWithBuffer{ - readBuf: new(bytes.Buffer), - writeBuf: new(bytes.Buffer), - } -} - -func (m *MockConnWithBuffer) Read(b []byte) (n int, err error) { - return m.readBuf.Read(b) -} - -func (m *MockConnWithBuffer) Write(b []byte) (n int, err error) { - return m.writeBuf.Write(b) -} - -func (m *MockConnWithBuffer) Close() error { - return nil -} - -func (m *MockConnWithBuffer) LocalAddr() net.Addr { - return nil -} - -func (m *MockConnWithBuffer) RemoteAddr() net.Addr { - return &net.IPAddr{IP: net.ParseIP("localhost")} -} - -func (m *MockConnWithBuffer) SetDeadline(t time.Time) error { - return nil -} - -func (m *MockConnWithBuffer) SetReadDeadline(t time.Time) error { - return nil -} - -func (m *MockConnWithBuffer) SetWriteDeadline(t time.Time) error { - return nil -} - -func TestHandleConnection(t *testing.T) { - tests := []struct { - name string - message *manager.ClientStreamMessage - }{ - { - name: "handle agent event", - message: &manager.ClientStreamMessage{ - Message: &manager.ClientStreamMessage_AgentEvent{ - AgentEvent: &manager.AgentEvent{ - EventType: "test_event", - ComputationId: "test_computation", - Status: "test_status", - Originator: "test_originator", - Timestamp: timestamppb.Now(), - Details: []byte("test_details"), - }, - }, - }, - }, - { - name: "handle agent log", - message: &manager.ClientStreamMessage{ - Message: &manager.ClientStreamMessage_AgentLog{ - AgentLog: &manager.AgentLog{ - ComputationId: "test_computation", - Timestamp: timestamppb.Now(), - }, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - mockConn := NewMockConnWithBuffer() - eventsChan := make(chan *manager.ClientStreamMessage, 1) - - e := &events{ - logger: mglog.NewMock(), - eventsChan: eventsChan, - reportBrokenConnection: func(address string) {}, - } - - data, err := proto.Marshal(tt.message) - assert.NoError(t, err) - - messageID := uint32(1) - err = binary.Write(mockConn.readBuf, binary.LittleEndian, messageID) - assert.NoError(t, err) - err = binary.Write(mockConn.readBuf, binary.LittleEndian, uint32(len(data))) - assert.NoError(t, err) - _, err = mockConn.readBuf.Write(data) - assert.NoError(t, err) - - // Add EOF to signal end of stream - err = binary.Write(mockConn.readBuf, binary.LittleEndian, uint32(0)) - assert.NoError(t, err) - err = binary.Write(mockConn.readBuf, binary.LittleEndian, uint32(0)) - assert.NoError(t, err) - - done := make(chan struct{}) - go func() { - e.handleConnection(mockConn) - close(done) - }() - - var receivedMessage *manager.ClientStreamMessage - select { - case receivedMessage = <-eventsChan: - case <-time.After(2 * time.Second): - t.Fatal("Timeout waiting for message in eventsChan") - } - - assert.NotNil(t, receivedMessage) - - select { - case <-done: - // handleConnection has exited - case <-time.After(2 * time.Second): - t.Fatal("Timeout waiting for handleConnection to exit") - } - - // Check if ack was written - var receivedAck uint32 - err = binary.Read(mockConn.writeBuf, binary.LittleEndian, &receivedAck) - assert.NoError(t, err) - assert.Equal(t, messageID, receivedAck) - - // Ensure no unexpected calls were made on the mock - mockConn.AssertExpectations(t) - }) - } -} diff --git a/manager/manager.pb.go b/manager/manager.pb.go index 62b1cd58..832e8d1a 100644 --- a/manager/manager.pb.go +++ b/manager/manager.pb.go @@ -12,7 +12,7 @@ package manager import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" + emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" ) @@ -24,27 +24,28 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Terminate struct { +type CreateRes struct { state protoimpl.MessageState `protogen:"open.v1"` - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + ForwardedPort string `protobuf:"bytes,1,opt,name=forwarded_port,json=forwardedPort,proto3" json:"forwarded_port,omitempty"` + SvmId string `protobuf:"bytes,2,opt,name=svm_id,json=svmId,proto3" json:"svm_id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Terminate) Reset() { - *x = Terminate{} +func (x *CreateRes) Reset() { + *x = CreateRes{} mi := &file_manager_manager_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Terminate) String() string { +func (x *CreateRes) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Terminate) ProtoMessage() {} +func (*CreateRes) ProtoMessage() {} -func (x *Terminate) ProtoReflect() protoreflect.Message { +func (x *CreateRes) ProtoReflect() protoreflect.Message { mi := &file_manager_manager_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -56,770 +57,92 @@ func (x *Terminate) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Terminate.ProtoReflect.Descriptor instead. -func (*Terminate) Descriptor() ([]byte, []int) { +// Deprecated: Use CreateRes.ProtoReflect.Descriptor instead. +func (*CreateRes) Descriptor() ([]byte, []int) { return file_manager_manager_proto_rawDescGZIP(), []int{0} } -func (x *Terminate) GetMessage() string { +func (x *CreateRes) GetForwardedPort() string { if x != nil { - return x.Message + return x.ForwardedPort } return "" } -type StopComputation struct { - state protoimpl.MessageState `protogen:"open.v1"` - ComputationId string `protobuf:"bytes,1,opt,name=computation_id,json=computationId,proto3" json:"computation_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *StopComputation) Reset() { - *x = StopComputation{} - mi := &file_manager_manager_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *StopComputation) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StopComputation) ProtoMessage() {} - -func (x *StopComputation) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StopComputation.ProtoReflect.Descriptor instead. -func (*StopComputation) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{1} -} - -func (x *StopComputation) GetComputationId() string { - if x != nil { - return x.ComputationId - } - return "" -} - -type StopComputationResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ComputationId string `protobuf:"bytes,1,opt,name=computation_id,json=computationId,proto3" json:"computation_id,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *StopComputationResponse) Reset() { - *x = StopComputationResponse{} - mi := &file_manager_manager_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *StopComputationResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StopComputationResponse) ProtoMessage() {} - -func (x *StopComputationResponse) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StopComputationResponse.ProtoReflect.Descriptor instead. -func (*StopComputationResponse) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{2} -} - -func (x *StopComputationResponse) GetComputationId() string { - if x != nil { - return x.ComputationId - } - return "" -} - -func (x *StopComputationResponse) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -type RunResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - AgentPort string `protobuf:"bytes,1,opt,name=agent_port,json=agentPort,proto3" json:"agent_port,omitempty"` - ComputationId string `protobuf:"bytes,2,opt,name=computation_id,json=computationId,proto3" json:"computation_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *RunResponse) Reset() { - *x = RunResponse{} - mi := &file_manager_manager_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *RunResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RunResponse) ProtoMessage() {} - -func (x *RunResponse) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RunResponse.ProtoReflect.Descriptor instead. -func (*RunResponse) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{3} -} - -func (x *RunResponse) GetAgentPort() string { - if x != nil { - return x.AgentPort - } - return "" -} - -func (x *RunResponse) GetComputationId() string { - if x != nil { - return x.ComputationId - } - return "" -} - -type AttestationPolicy struct { - state protoimpl.MessageState `protogen:"open.v1"` - Info []byte `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AttestationPolicy) Reset() { - *x = AttestationPolicy{} - mi := &file_manager_manager_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AttestationPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AttestationPolicy) ProtoMessage() {} - -func (x *AttestationPolicy) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AttestationPolicy.ProtoReflect.Descriptor instead. -func (*AttestationPolicy) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{4} -} - -func (x *AttestationPolicy) GetInfo() []byte { - if x != nil { - return x.Info - } - return nil -} - -func (x *AttestationPolicy) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type SVMInfo struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - OvmfVersion string `protobuf:"bytes,2,opt,name=ovmf_version,json=ovmfVersion,proto3" json:"ovmf_version,omitempty"` - CpuNum int32 `protobuf:"varint,3,opt,name=cpu_num,json=cpuNum,proto3" json:"cpu_num,omitempty"` - CpuType string `protobuf:"bytes,4,opt,name=cpu_type,json=cpuType,proto3" json:"cpu_type,omitempty"` - KernelCmd string `protobuf:"bytes,5,opt,name=kernel_cmd,json=kernelCmd,proto3" json:"kernel_cmd,omitempty"` - EosVersion string `protobuf:"bytes,6,opt,name=eos_version,json=eosVersion,proto3" json:"eos_version,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SVMInfo) Reset() { - *x = SVMInfo{} - mi := &file_manager_manager_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SVMInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SVMInfo) ProtoMessage() {} - -func (x *SVMInfo) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SVMInfo.ProtoReflect.Descriptor instead. -func (*SVMInfo) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{5} -} - -func (x *SVMInfo) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *SVMInfo) GetOvmfVersion() string { - if x != nil { - return x.OvmfVersion - } - return "" -} - -func (x *SVMInfo) GetCpuNum() int32 { - if x != nil { - return x.CpuNum - } - return 0 -} - -func (x *SVMInfo) GetCpuType() string { - if x != nil { - return x.CpuType - } - return "" -} - -func (x *SVMInfo) GetKernelCmd() string { - if x != nil { - return x.KernelCmd - } - return "" -} - -func (x *SVMInfo) GetEosVersion() string { - if x != nil { - return x.EosVersion - } - return "" -} - -type AgentEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - EventType string `protobuf:"bytes,1,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` - Timestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - ComputationId string `protobuf:"bytes,3,opt,name=computation_id,json=computationId,proto3" json:"computation_id,omitempty"` - Details []byte `protobuf:"bytes,4,opt,name=details,proto3" json:"details,omitempty"` - Originator string `protobuf:"bytes,5,opt,name=originator,proto3" json:"originator,omitempty"` - Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AgentEvent) Reset() { - *x = AgentEvent{} - mi := &file_manager_manager_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AgentEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AgentEvent) ProtoMessage() {} - -func (x *AgentEvent) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[6] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AgentEvent.ProtoReflect.Descriptor instead. -func (*AgentEvent) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{6} -} - -func (x *AgentEvent) GetEventType() string { - if x != nil { - return x.EventType - } - return "" -} - -func (x *AgentEvent) GetTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.Timestamp - } - return nil -} - -func (x *AgentEvent) GetComputationId() string { - if x != nil { - return x.ComputationId - } - return "" -} - -func (x *AgentEvent) GetDetails() []byte { - if x != nil { - return x.Details - } - return nil -} - -func (x *AgentEvent) GetOriginator() string { - if x != nil { - return x.Originator - } - return "" -} - -func (x *AgentEvent) GetStatus() string { - if x != nil { - return x.Status - } - return "" -} - -type AgentLog struct { - state protoimpl.MessageState `protogen:"open.v1"` - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - ComputationId string `protobuf:"bytes,2,opt,name=computation_id,json=computationId,proto3" json:"computation_id,omitempty"` - Level string `protobuf:"bytes,3,opt,name=level,proto3" json:"level,omitempty"` - Timestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AgentLog) Reset() { - *x = AgentLog{} - mi := &file_manager_manager_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AgentLog) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AgentLog) ProtoMessage() {} - -func (x *AgentLog) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[7] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AgentLog.ProtoReflect.Descriptor instead. -func (*AgentLog) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{7} -} - -func (x *AgentLog) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -func (x *AgentLog) GetComputationId() string { - if x != nil { - return x.ComputationId - } - return "" -} - -func (x *AgentLog) GetLevel() string { - if x != nil { - return x.Level - } - return "" -} - -func (x *AgentLog) GetTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.Timestamp - } - return nil -} - -type ClientStreamMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Message: - // - // *ClientStreamMessage_AgentLog - // *ClientStreamMessage_AgentEvent - // *ClientStreamMessage_RunRes - // *ClientStreamMessage_AttestationPolicy - // *ClientStreamMessage_StopComputationRes - // *ClientStreamMessage_SvmInfo - Message isClientStreamMessage_Message `protobuf_oneof:"message"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ClientStreamMessage) Reset() { - *x = ClientStreamMessage{} - mi := &file_manager_manager_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ClientStreamMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClientStreamMessage) ProtoMessage() {} - -func (x *ClientStreamMessage) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[8] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClientStreamMessage.ProtoReflect.Descriptor instead. -func (*ClientStreamMessage) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{8} -} - -func (x *ClientStreamMessage) GetMessage() isClientStreamMessage_Message { - if x != nil { - return x.Message - } - return nil -} - -func (x *ClientStreamMessage) GetAgentLog() *AgentLog { - if x != nil { - if x, ok := x.Message.(*ClientStreamMessage_AgentLog); ok { - return x.AgentLog - } - } - return nil -} - -func (x *ClientStreamMessage) GetAgentEvent() *AgentEvent { - if x != nil { - if x, ok := x.Message.(*ClientStreamMessage_AgentEvent); ok { - return x.AgentEvent - } - } - return nil -} - -func (x *ClientStreamMessage) GetRunRes() *RunResponse { - if x != nil { - if x, ok := x.Message.(*ClientStreamMessage_RunRes); ok { - return x.RunRes - } - } - return nil -} - -func (x *ClientStreamMessage) GetAttestationPolicy() *AttestationPolicy { - if x != nil { - if x, ok := x.Message.(*ClientStreamMessage_AttestationPolicy); ok { - return x.AttestationPolicy - } - } - return nil -} - -func (x *ClientStreamMessage) GetStopComputationRes() *StopComputationResponse { - if x != nil { - if x, ok := x.Message.(*ClientStreamMessage_StopComputationRes); ok { - return x.StopComputationRes - } - } - return nil -} - -func (x *ClientStreamMessage) GetSvmInfo() *SVMInfo { - if x != nil { - if x, ok := x.Message.(*ClientStreamMessage_SvmInfo); ok { - return x.SvmInfo - } - } - return nil -} - -type isClientStreamMessage_Message interface { - isClientStreamMessage_Message() -} - -type ClientStreamMessage_AgentLog struct { - AgentLog *AgentLog `protobuf:"bytes,1,opt,name=agent_log,json=agentLog,proto3,oneof"` -} - -type ClientStreamMessage_AgentEvent struct { - AgentEvent *AgentEvent `protobuf:"bytes,2,opt,name=agent_event,json=agentEvent,proto3,oneof"` -} - -type ClientStreamMessage_RunRes struct { - RunRes *RunResponse `protobuf:"bytes,3,opt,name=run_res,json=runRes,proto3,oneof"` -} - -type ClientStreamMessage_AttestationPolicy struct { - AttestationPolicy *AttestationPolicy `protobuf:"bytes,4,opt,name=attestationPolicy,proto3,oneof"` -} - -type ClientStreamMessage_StopComputationRes struct { - StopComputationRes *StopComputationResponse `protobuf:"bytes,5,opt,name=stopComputationRes,proto3,oneof"` -} - -type ClientStreamMessage_SvmInfo struct { - SvmInfo *SVMInfo `protobuf:"bytes,6,opt,name=svm_info,json=svmInfo,proto3,oneof"` -} - -func (*ClientStreamMessage_AgentLog) isClientStreamMessage_Message() {} - -func (*ClientStreamMessage_AgentEvent) isClientStreamMessage_Message() {} - -func (*ClientStreamMessage_RunRes) isClientStreamMessage_Message() {} - -func (*ClientStreamMessage_AttestationPolicy) isClientStreamMessage_Message() {} - -func (*ClientStreamMessage_StopComputationRes) isClientStreamMessage_Message() {} - -func (*ClientStreamMessage_SvmInfo) isClientStreamMessage_Message() {} - -type ServerStreamMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Message: - // - // *ServerStreamMessage_RunReqChunks - // *ServerStreamMessage_RunReq - // *ServerStreamMessage_TerminateReq - // *ServerStreamMessage_StopComputation - // *ServerStreamMessage_AttestationPolicyReq - // *ServerStreamMessage_SvmInfoReq - Message isServerStreamMessage_Message `protobuf_oneof:"message"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ServerStreamMessage) Reset() { - *x = ServerStreamMessage{} - mi := &file_manager_manager_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ServerStreamMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServerStreamMessage) ProtoMessage() {} - -func (x *ServerStreamMessage) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[9] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServerStreamMessage.ProtoReflect.Descriptor instead. -func (*ServerStreamMessage) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{9} -} - -func (x *ServerStreamMessage) GetMessage() isServerStreamMessage_Message { - if x != nil { - return x.Message - } - return nil -} - -func (x *ServerStreamMessage) GetRunReqChunks() *RunReqChunks { - if x != nil { - if x, ok := x.Message.(*ServerStreamMessage_RunReqChunks); ok { - return x.RunReqChunks - } - } - return nil -} - -func (x *ServerStreamMessage) GetRunReq() *ComputationRunReq { - if x != nil { - if x, ok := x.Message.(*ServerStreamMessage_RunReq); ok { - return x.RunReq - } - } - return nil -} - -func (x *ServerStreamMessage) GetTerminateReq() *Terminate { - if x != nil { - if x, ok := x.Message.(*ServerStreamMessage_TerminateReq); ok { - return x.TerminateReq - } - } - return nil -} - -func (x *ServerStreamMessage) GetStopComputation() *StopComputation { - if x != nil { - if x, ok := x.Message.(*ServerStreamMessage_StopComputation); ok { - return x.StopComputation - } - } - return nil -} - -func (x *ServerStreamMessage) GetAttestationPolicyReq() *AttestationPolicyReq { - if x != nil { - if x, ok := x.Message.(*ServerStreamMessage_AttestationPolicyReq); ok { - return x.AttestationPolicyReq - } - } - return nil -} - -func (x *ServerStreamMessage) GetSvmInfoReq() *SVMInfoReq { +func (x *CreateRes) GetSvmId() string { if x != nil { - if x, ok := x.Message.(*ServerStreamMessage_SvmInfoReq); ok { - return x.SvmInfoReq - } + return x.SvmId } - return nil + return "" } -type isServerStreamMessage_Message interface { - isServerStreamMessage_Message() +type RemoveReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + SvmId string `protobuf:"bytes,1,opt,name=svm_id,json=svmId,proto3" json:"svm_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -type ServerStreamMessage_RunReqChunks struct { - RunReqChunks *RunReqChunks `protobuf:"bytes,1,opt,name=runReqChunks,proto3,oneof"` +func (x *RemoveReq) Reset() { + *x = RemoveReq{} + mi := &file_manager_manager_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -type ServerStreamMessage_RunReq struct { - RunReq *ComputationRunReq `protobuf:"bytes,2,opt,name=runReq,proto3,oneof"` +func (x *RemoveReq) String() string { + return protoimpl.X.MessageStringOf(x) } -type ServerStreamMessage_TerminateReq struct { - TerminateReq *Terminate `protobuf:"bytes,3,opt,name=terminateReq,proto3,oneof"` -} +func (*RemoveReq) ProtoMessage() {} -type ServerStreamMessage_StopComputation struct { - StopComputation *StopComputation `protobuf:"bytes,4,opt,name=stopComputation,proto3,oneof"` +func (x *RemoveReq) ProtoReflect() protoreflect.Message { + mi := &file_manager_manager_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -type ServerStreamMessage_AttestationPolicyReq struct { - AttestationPolicyReq *AttestationPolicyReq `protobuf:"bytes,5,opt,name=attestationPolicyReq,proto3,oneof"` +// Deprecated: Use RemoveReq.ProtoReflect.Descriptor instead. +func (*RemoveReq) Descriptor() ([]byte, []int) { + return file_manager_manager_proto_rawDescGZIP(), []int{1} } -type ServerStreamMessage_SvmInfoReq struct { - SvmInfoReq *SVMInfoReq `protobuf:"bytes,6,opt,name=svmInfoReq,proto3,oneof"` +func (x *RemoveReq) GetSvmId() string { + if x != nil { + return x.SvmId + } + return "" } -func (*ServerStreamMessage_RunReqChunks) isServerStreamMessage_Message() {} - -func (*ServerStreamMessage_RunReq) isServerStreamMessage_Message() {} - -func (*ServerStreamMessage_TerminateReq) isServerStreamMessage_Message() {} - -func (*ServerStreamMessage_StopComputation) isServerStreamMessage_Message() {} - -func (*ServerStreamMessage_AttestationPolicyReq) isServerStreamMessage_Message() {} - -func (*ServerStreamMessage_SvmInfoReq) isServerStreamMessage_Message() {} - -type RunReqChunks struct { +type AttestationPolicyRes struct { state protoimpl.MessageState `protogen:"open.v1"` - Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + Info []byte `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - IsLast bool `protobuf:"varint,3,opt,name=is_last,json=isLast,proto3" json:"is_last,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *RunReqChunks) Reset() { - *x = RunReqChunks{} - mi := &file_manager_manager_proto_msgTypes[10] +func (x *AttestationPolicyRes) Reset() { + *x = AttestationPolicyRes{} + mi := &file_manager_manager_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *RunReqChunks) String() string { +func (x *AttestationPolicyRes) String() string { return protoimpl.X.MessageStringOf(x) } -func (*RunReqChunks) ProtoMessage() {} +func (*AttestationPolicyRes) ProtoMessage() {} -func (x *RunReqChunks) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[10] +func (x *AttestationPolicyRes) ProtoReflect() protoreflect.Message { + mi := &file_manager_manager_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -830,60 +153,52 @@ func (x *RunReqChunks) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use RunReqChunks.ProtoReflect.Descriptor instead. -func (*RunReqChunks) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{10} +// Deprecated: Use AttestationPolicyRes.ProtoReflect.Descriptor instead. +func (*AttestationPolicyRes) Descriptor() ([]byte, []int) { + return file_manager_manager_proto_rawDescGZIP(), []int{2} } -func (x *RunReqChunks) GetData() []byte { +func (x *AttestationPolicyRes) GetInfo() []byte { if x != nil { - return x.Data + return x.Info } return nil } -func (x *RunReqChunks) GetId() string { +func (x *AttestationPolicyRes) GetId() string { if x != nil { return x.Id } return "" } -func (x *RunReqChunks) GetIsLast() bool { - if x != nil { - return x.IsLast - } - return false -} - -type ComputationRunReq struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Datasets []*Dataset `protobuf:"bytes,4,rep,name=datasets,proto3" json:"datasets,omitempty"` - Algorithm *Algorithm `protobuf:"bytes,5,opt,name=algorithm,proto3" json:"algorithm,omitempty"` - ResultConsumers []*ResultConsumer `protobuf:"bytes,6,rep,name=result_consumers,json=resultConsumers,proto3" json:"result_consumers,omitempty"` - AgentConfig *AgentConfig `protobuf:"bytes,7,opt,name=agent_config,json=agentConfig,proto3" json:"agent_config,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type SVMInfoRes struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + OvmfVersion string `protobuf:"bytes,2,opt,name=ovmf_version,json=ovmfVersion,proto3" json:"ovmf_version,omitempty"` + CpuNum int32 `protobuf:"varint,3,opt,name=cpu_num,json=cpuNum,proto3" json:"cpu_num,omitempty"` + CpuType string `protobuf:"bytes,4,opt,name=cpu_type,json=cpuType,proto3" json:"cpu_type,omitempty"` + KernelCmd string `protobuf:"bytes,5,opt,name=kernel_cmd,json=kernelCmd,proto3" json:"kernel_cmd,omitempty"` + EosVersion string `protobuf:"bytes,6,opt,name=eos_version,json=eosVersion,proto3" json:"eos_version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ComputationRunReq) Reset() { - *x = ComputationRunReq{} - mi := &file_manager_manager_proto_msgTypes[11] +func (x *SVMInfoRes) Reset() { + *x = SVMInfoRes{} + mi := &file_manager_manager_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ComputationRunReq) String() string { +func (x *SVMInfoRes) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ComputationRunReq) ProtoMessage() {} +func (*SVMInfoRes) ProtoMessage() {} -func (x *ComputationRunReq) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[11] +func (x *SVMInfoRes) ProtoReflect() protoreflect.Message { + mi := &file_manager_manager_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -894,58 +209,51 @@ func (x *ComputationRunReq) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ComputationRunReq.ProtoReflect.Descriptor instead. -func (*ComputationRunReq) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{11} +// Deprecated: Use SVMInfoRes.ProtoReflect.Descriptor instead. +func (*SVMInfoRes) Descriptor() ([]byte, []int) { + return file_manager_manager_proto_rawDescGZIP(), []int{3} } -func (x *ComputationRunReq) GetId() string { +func (x *SVMInfoRes) GetId() string { if x != nil { return x.Id } return "" } -func (x *ComputationRunReq) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ComputationRunReq) GetDescription() string { +func (x *SVMInfoRes) GetOvmfVersion() string { if x != nil { - return x.Description + return x.OvmfVersion } return "" } -func (x *ComputationRunReq) GetDatasets() []*Dataset { +func (x *SVMInfoRes) GetCpuNum() int32 { if x != nil { - return x.Datasets + return x.CpuNum } - return nil + return 0 } -func (x *ComputationRunReq) GetAlgorithm() *Algorithm { +func (x *SVMInfoRes) GetCpuType() string { if x != nil { - return x.Algorithm + return x.CpuType } - return nil + return "" } -func (x *ComputationRunReq) GetResultConsumers() []*ResultConsumer { +func (x *SVMInfoRes) GetKernelCmd() string { if x != nil { - return x.ResultConsumers + return x.KernelCmd } - return nil + return "" } -func (x *ComputationRunReq) GetAgentConfig() *AgentConfig { +func (x *SVMInfoRes) GetEosVersion() string { if x != nil { - return x.AgentConfig + return x.EosVersion } - return nil + return "" } type AttestationPolicyReq struct { @@ -957,7 +265,7 @@ type AttestationPolicyReq struct { func (x *AttestationPolicyReq) Reset() { *x = AttestationPolicyReq{} - mi := &file_manager_manager_proto_msgTypes[12] + mi := &file_manager_manager_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -969,7 +277,7 @@ func (x *AttestationPolicyReq) String() string { func (*AttestationPolicyReq) ProtoMessage() {} func (x *AttestationPolicyReq) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[12] + mi := &file_manager_manager_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -982,7 +290,7 @@ func (x *AttestationPolicyReq) ProtoReflect() protoreflect.Message { // Deprecated: Use AttestationPolicyReq.ProtoReflect.Descriptor instead. func (*AttestationPolicyReq) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{12} + return file_manager_manager_proto_rawDescGZIP(), []int{4} } func (x *AttestationPolicyReq) GetId() string { @@ -1001,7 +309,7 @@ type SVMInfoReq struct { func (x *SVMInfoReq) Reset() { *x = SVMInfoReq{} - mi := &file_manager_manager_proto_msgTypes[13] + mi := &file_manager_manager_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1013,7 +321,7 @@ func (x *SVMInfoReq) String() string { func (*SVMInfoReq) ProtoMessage() {} func (x *SVMInfoReq) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[13] + mi := &file_manager_manager_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1026,7 +334,7 @@ func (x *SVMInfoReq) ProtoReflect() protoreflect.Message { // Deprecated: Use SVMInfoReq.ProtoReflect.Descriptor instead. func (*SVMInfoReq) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{13} + return file_manager_manager_proto_rawDescGZIP(), []int{5} } func (x *SVMInfoReq) GetId() string { @@ -1036,440 +344,58 @@ func (x *SVMInfoReq) GetId() string { return "" } -type ResultConsumer struct { - state protoimpl.MessageState `protogen:"open.v1"` - UserKey []byte `protobuf:"bytes,1,opt,name=userKey,proto3" json:"userKey,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ResultConsumer) Reset() { - *x = ResultConsumer{} - mi := &file_manager_manager_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ResultConsumer) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResultConsumer) ProtoMessage() {} - -func (x *ResultConsumer) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[14] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResultConsumer.ProtoReflect.Descriptor instead. -func (*ResultConsumer) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{14} -} - -func (x *ResultConsumer) GetUserKey() []byte { - if x != nil { - return x.UserKey - } - return nil -} - -type Dataset struct { - state protoimpl.MessageState `protogen:"open.v1"` - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` // should be sha3.Sum256, 32 byte length. - UserKey []byte `protobuf:"bytes,2,opt,name=userKey,proto3" json:"userKey,omitempty"` - Filename string `protobuf:"bytes,3,opt,name=filename,proto3" json:"filename,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Dataset) Reset() { - *x = Dataset{} - mi := &file_manager_manager_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Dataset) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Dataset) ProtoMessage() {} - -func (x *Dataset) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[15] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Dataset.ProtoReflect.Descriptor instead. -func (*Dataset) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{15} -} - -func (x *Dataset) GetHash() []byte { - if x != nil { - return x.Hash - } - return nil -} - -func (x *Dataset) GetUserKey() []byte { - if x != nil { - return x.UserKey - } - return nil -} - -func (x *Dataset) GetFilename() string { - if x != nil { - return x.Filename - } - return "" -} - -type Algorithm struct { - state protoimpl.MessageState `protogen:"open.v1"` - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` // should be sha3.Sum256, 32 byte length. - UserKey []byte `protobuf:"bytes,2,opt,name=userKey,proto3" json:"userKey,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Algorithm) Reset() { - *x = Algorithm{} - mi := &file_manager_manager_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Algorithm) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Algorithm) ProtoMessage() {} - -func (x *Algorithm) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[16] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Algorithm.ProtoReflect.Descriptor instead. -func (*Algorithm) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{16} -} - -func (x *Algorithm) GetHash() []byte { - if x != nil { - return x.Hash - } - return nil -} - -func (x *Algorithm) GetUserKey() []byte { - if x != nil { - return x.UserKey - } - return nil -} - -type AgentConfig struct { - state protoimpl.MessageState `protogen:"open.v1"` - Port string `protobuf:"bytes,1,opt,name=port,proto3" json:"port,omitempty"` - Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"` - CertFile string `protobuf:"bytes,3,opt,name=cert_file,json=certFile,proto3" json:"cert_file,omitempty"` - KeyFile string `protobuf:"bytes,4,opt,name=key_file,json=keyFile,proto3" json:"key_file,omitempty"` - ClientCaFile string `protobuf:"bytes,5,opt,name=client_ca_file,json=clientCaFile,proto3" json:"client_ca_file,omitempty"` - ServerCaFile string `protobuf:"bytes,6,opt,name=server_ca_file,json=serverCaFile,proto3" json:"server_ca_file,omitempty"` - LogLevel string `protobuf:"bytes,7,opt,name=log_level,json=logLevel,proto3" json:"log_level,omitempty"` - AttestedTls bool `protobuf:"varint,8,opt,name=attested_tls,json=attestedTls,proto3" json:"attested_tls,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AgentConfig) Reset() { - *x = AgentConfig{} - mi := &file_manager_manager_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AgentConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AgentConfig) ProtoMessage() {} - -func (x *AgentConfig) ProtoReflect() protoreflect.Message { - mi := &file_manager_manager_proto_msgTypes[17] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AgentConfig.ProtoReflect.Descriptor instead. -func (*AgentConfig) Descriptor() ([]byte, []int) { - return file_manager_manager_proto_rawDescGZIP(), []int{17} -} - -func (x *AgentConfig) GetPort() string { - if x != nil { - return x.Port - } - return "" -} - -func (x *AgentConfig) GetHost() string { - if x != nil { - return x.Host - } - return "" -} - -func (x *AgentConfig) GetCertFile() string { - if x != nil { - return x.CertFile - } - return "" -} - -func (x *AgentConfig) GetKeyFile() string { - if x != nil { - return x.KeyFile - } - return "" -} - -func (x *AgentConfig) GetClientCaFile() string { - if x != nil { - return x.ClientCaFile - } - return "" -} - -func (x *AgentConfig) GetServerCaFile() string { - if x != nil { - return x.ServerCaFile - } - return "" -} - -func (x *AgentConfig) GetLogLevel() string { - if x != nil { - return x.LogLevel - } - return "" -} - -func (x *AgentConfig) GetAttestedTls() bool { - if x != nil { - return x.AttestedTls - } - return false -} - var File_manager_manager_proto protoreflect.FileDescriptor var file_manager_manager_proto_rawDesc = []byte{ 0x0a, 0x15, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x25, 0x0a, 0x09, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x38, 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x70, - 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x63, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x22, 0x5a, 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x53, - 0x0a, 0x0b, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x25, 0x0a, 0x0e, - 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x22, 0x37, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xb0, 0x01, 0x0a, - 0x07, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x76, 0x6d, 0x66, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x6f, 0x76, 0x6d, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x63, - 0x70, 0x75, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x70, - 0x75, 0x4e, 0x75, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x70, 0x75, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6d, 0x64, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x43, 0x6d, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x65, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0xde, 0x01, 0x0a, 0x0a, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, - 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, - 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x9b, 0x01, 0x0a, 0x08, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x8a, - 0x03, 0x0a, 0x13, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, - 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x08, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x2f, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x06, 0x72, 0x75, 0x6e, 0x52, 0x65, - 0x73, 0x12, 0x4a, 0x0a, 0x11, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x11, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x52, 0x0a, - 0x12, 0x73, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x12, 0x73, - 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x73, 0x76, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x56, - 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x07, 0x73, 0x76, 0x6d, 0x49, 0x6e, 0x66, 0x6f, - 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9f, 0x03, 0x0a, 0x13, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x43, 0x68, 0x75, - 0x6e, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, - 0x48, 0x00, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, - 0x12, 0x34, 0x0a, 0x06, 0x72, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x06, - 0x72, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, - 0x48, 0x00, 0x52, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x12, 0x44, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x14, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x41, - 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x14, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x35, 0x0a, 0x0a, 0x73, - 0x76, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x76, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x4b, 0x0a, - 0x0c, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4c, 0x61, 0x73, 0x74, 0x22, 0xb6, 0x02, 0x0a, 0x11, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x73, 0x65, - 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, - 0x73, 0x65, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, - 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x09, 0x61, 0x6c, 0x67, - 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x42, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x22, 0x26, 0x0a, 0x14, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1c, 0x0a, 0x0a, 0x53, - 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2a, 0x0a, 0x0e, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x75, - 0x73, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x4b, 0x65, 0x79, 0x22, 0x53, 0x0a, 0x07, 0x44, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x68, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x1a, - 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x39, 0x0a, 0x09, 0x41, 0x6c, - 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x75, - 0x73, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x4b, 0x65, 0x79, 0x22, 0xf9, 0x01, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, - 0x79, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, - 0x63, 0x61, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x46, 0x69, 0x6c, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x21, - 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x6c, 0x73, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x6c, - 0x73, 0x32, 0x5d, 0x0a, 0x0e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1c, - 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, - 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x49, 0x0a, + 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x76, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x73, 0x76, 0x6d, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x09, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x76, 0x6d, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x76, 0x6d, 0x49, 0x64, 0x22, 0x3a, 0x0a, 0x14, + 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x0a, 0x53, 0x56, 0x4d, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x76, 0x6d, 0x66, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, + 0x76, 0x6d, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x70, + 0x75, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x70, 0x75, + 0x4e, 0x75, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x70, 0x75, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6d, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x43, 0x6d, 0x64, 0x12, 0x1f, 0x0a, + 0x0b, 0x65, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x26, + 0x0a, 0x14, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1c, 0x0a, 0x0a, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x32, 0x90, 0x02, 0x0a, 0x0e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x56, 0x6d, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x22, + 0x00, 0x12, 0x38, 0x0a, 0x08, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6d, 0x12, 0x12, 0x2e, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, + 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x07, 0x53, + 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x13, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x2e, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x22, 0x00, 0x12, 0x53, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1484,54 +410,30 @@ func file_manager_manager_proto_rawDescGZIP() []byte { return file_manager_manager_proto_rawDescData } -var file_manager_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_manager_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_manager_manager_proto_goTypes = []any{ - (*Terminate)(nil), // 0: manager.Terminate - (*StopComputation)(nil), // 1: manager.StopComputation - (*StopComputationResponse)(nil), // 2: manager.StopComputationResponse - (*RunResponse)(nil), // 3: manager.RunResponse - (*AttestationPolicy)(nil), // 4: manager.AttestationPolicy - (*SVMInfo)(nil), // 5: manager.SVMInfo - (*AgentEvent)(nil), // 6: manager.AgentEvent - (*AgentLog)(nil), // 7: manager.AgentLog - (*ClientStreamMessage)(nil), // 8: manager.ClientStreamMessage - (*ServerStreamMessage)(nil), // 9: manager.ServerStreamMessage - (*RunReqChunks)(nil), // 10: manager.RunReqChunks - (*ComputationRunReq)(nil), // 11: manager.ComputationRunReq - (*AttestationPolicyReq)(nil), // 12: manager.AttestationPolicyReq - (*SVMInfoReq)(nil), // 13: manager.SVMInfoReq - (*ResultConsumer)(nil), // 14: manager.ResultConsumer - (*Dataset)(nil), // 15: manager.Dataset - (*Algorithm)(nil), // 16: manager.Algorithm - (*AgentConfig)(nil), // 17: manager.AgentConfig - (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp + (*CreateRes)(nil), // 0: manager.CreateRes + (*RemoveReq)(nil), // 1: manager.RemoveReq + (*AttestationPolicyRes)(nil), // 2: manager.AttestationPolicyRes + (*SVMInfoRes)(nil), // 3: manager.SVMInfoRes + (*AttestationPolicyReq)(nil), // 4: manager.AttestationPolicyReq + (*SVMInfoReq)(nil), // 5: manager.SVMInfoReq + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty } var file_manager_manager_proto_depIdxs = []int32{ - 18, // 0: manager.AgentEvent.timestamp:type_name -> google.protobuf.Timestamp - 18, // 1: manager.AgentLog.timestamp:type_name -> google.protobuf.Timestamp - 7, // 2: manager.ClientStreamMessage.agent_log:type_name -> manager.AgentLog - 6, // 3: manager.ClientStreamMessage.agent_event:type_name -> manager.AgentEvent - 3, // 4: manager.ClientStreamMessage.run_res:type_name -> manager.RunResponse - 4, // 5: manager.ClientStreamMessage.attestationPolicy:type_name -> manager.AttestationPolicy - 2, // 6: manager.ClientStreamMessage.stopComputationRes:type_name -> manager.StopComputationResponse - 5, // 7: manager.ClientStreamMessage.svm_info:type_name -> manager.SVMInfo - 10, // 8: manager.ServerStreamMessage.runReqChunks:type_name -> manager.RunReqChunks - 11, // 9: manager.ServerStreamMessage.runReq:type_name -> manager.ComputationRunReq - 0, // 10: manager.ServerStreamMessage.terminateReq:type_name -> manager.Terminate - 1, // 11: manager.ServerStreamMessage.stopComputation:type_name -> manager.StopComputation - 12, // 12: manager.ServerStreamMessage.attestationPolicyReq:type_name -> manager.AttestationPolicyReq - 13, // 13: manager.ServerStreamMessage.svmInfoReq:type_name -> manager.SVMInfoReq - 15, // 14: manager.ComputationRunReq.datasets:type_name -> manager.Dataset - 16, // 15: manager.ComputationRunReq.algorithm:type_name -> manager.Algorithm - 14, // 16: manager.ComputationRunReq.result_consumers:type_name -> manager.ResultConsumer - 17, // 17: manager.ComputationRunReq.agent_config:type_name -> manager.AgentConfig - 8, // 18: manager.ManagerService.Process:input_type -> manager.ClientStreamMessage - 9, // 19: manager.ManagerService.Process:output_type -> manager.ServerStreamMessage - 19, // [19:20] is the sub-list for method output_type - 18, // [18:19] is the sub-list for method input_type - 18, // [18:18] is the sub-list for extension type_name - 18, // [18:18] is the sub-list for extension extendee - 0, // [0:18] is the sub-list for field type_name + 6, // 0: manager.ManagerService.CreateVm:input_type -> google.protobuf.Empty + 1, // 1: manager.ManagerService.RemoveVm:input_type -> manager.RemoveReq + 5, // 2: manager.ManagerService.SVMInfo:input_type -> manager.SVMInfoReq + 4, // 3: manager.ManagerService.AttestationPolicy:input_type -> manager.AttestationPolicyReq + 0, // 4: manager.ManagerService.CreateVm:output_type -> manager.CreateRes + 6, // 5: manager.ManagerService.RemoveVm:output_type -> google.protobuf.Empty + 3, // 6: manager.ManagerService.SVMInfo:output_type -> manager.SVMInfoRes + 2, // 7: manager.ManagerService.AttestationPolicy:output_type -> manager.AttestationPolicyRes + 4, // [4:8] is the sub-list for method output_type + 0, // [0:4] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_manager_manager_proto_init() } @@ -1539,29 +441,13 @@ func file_manager_manager_proto_init() { if File_manager_manager_proto != nil { return } - file_manager_manager_proto_msgTypes[8].OneofWrappers = []any{ - (*ClientStreamMessage_AgentLog)(nil), - (*ClientStreamMessage_AgentEvent)(nil), - (*ClientStreamMessage_RunRes)(nil), - (*ClientStreamMessage_AttestationPolicy)(nil), - (*ClientStreamMessage_StopComputationRes)(nil), - (*ClientStreamMessage_SvmInfo)(nil), - } - file_manager_manager_proto_msgTypes[9].OneofWrappers = []any{ - (*ServerStreamMessage_RunReqChunks)(nil), - (*ServerStreamMessage_RunReq)(nil), - (*ServerStreamMessage_TerminateReq)(nil), - (*ServerStreamMessage_StopComputation)(nil), - (*ServerStreamMessage_AttestationPolicyReq)(nil), - (*ServerStreamMessage_SvmInfoReq)(nil), - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_manager_manager_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/manager/manager.proto b/manager/manager.proto index dbe5885b..5ec04352 100644 --- a/manager/manager.proto +++ b/manager/manager.proto @@ -3,40 +3,34 @@ syntax = "proto3"; -import "google/protobuf/timestamp.proto"; +import "google/protobuf/empty.proto"; package manager; option go_package = "./manager"; service ManagerService { - rpc Process(stream ClientStreamMessage) returns (stream ServerStreamMessage) {} + rpc CreateVm(google.protobuf.Empty) returns (CreateRes) {} + rpc RemoveVm(RemoveReq) returns (google.protobuf.Empty) {} + rpc SVMInfo(SVMInfoReq) returns (SVMInfoRes) {} + rpc AttestationPolicy(AttestationPolicyReq) returns (AttestationPolicyRes) {} } -message Terminate { - string message = 1; +message CreateRes{ + string forwarded_port = 1; + string svm_id = 2; } -message StopComputation { - string computation_id = 1; +message RemoveReq{ + string svm_id = 1; } -message StopComputationResponse { - string computation_id = 1; - string message = 2; -} - -message RunResponse{ - string agent_port = 1; - string computation_id = 2; -} - -message AttestationPolicy{ +message AttestationPolicyRes{ bytes info = 1; string id = 2; } -message SVMInfo{ +message SVMInfoRes{ string id = 1; string ovmf_version = 2; int32 cpu_num = 3; @@ -45,60 +39,6 @@ message SVMInfo{ string eos_version = 6; } -message AgentEvent { - string event_type = 1; - google.protobuf.Timestamp timestamp = 2; - string computation_id = 3; - bytes details = 4; - string originator = 5; - string status = 6; -} - -message AgentLog { - string message = 1; - string computation_id = 2; - string level = 3; - google.protobuf.Timestamp timestamp = 4; -} - -message ClientStreamMessage { - oneof message { - AgentLog agent_log = 1; - AgentEvent agent_event = 2; - RunResponse run_res = 3; - AttestationPolicy attestationPolicy = 4; - StopComputationResponse stopComputationRes = 5; - SVMInfo svm_info = 6; - } -} - -message ServerStreamMessage { - oneof message { - RunReqChunks runReqChunks = 1; - ComputationRunReq runReq = 2; - Terminate terminateReq = 3; - StopComputation stopComputation = 4; - AttestationPolicyReq attestationPolicyReq = 5; - SVMInfoReq svmInfoReq = 6; - } -} - -message RunReqChunks { - bytes data = 1; - string id = 2; - bool is_last = 3; -} - -message ComputationRunReq { - string id = 1; - string name = 2; - string description = 3; - repeated Dataset datasets = 4; - Algorithm algorithm = 5; - repeated ResultConsumer result_consumers = 6; - AgentConfig agent_config = 7; -} - message AttestationPolicyReq { string id = 1; } @@ -107,29 +47,3 @@ message SVMInfoReq { string id = 1; } -message ResultConsumer { - bytes userKey = 1; -} - -message Dataset { - bytes hash = 1; // should be sha3.Sum256, 32 byte length. - bytes userKey = 2; - string filename = 3; -} - -message Algorithm { - bytes hash = 1; // should be sha3.Sum256, 32 byte length. - bytes userKey = 2; -} - -message AgentConfig { - string port = 1; - string host = 2; - string cert_file = 3; - string key_file = 4; - string client_ca_file = 5; - string server_ca_file = 6; - string log_level = 7; - bool attested_tls = 8; -} - diff --git a/manager/manager_grpc.pb.go b/manager/manager_grpc.pb.go index e7060063..2e9f5bc8 100644 --- a/manager/manager_grpc.pb.go +++ b/manager/manager_grpc.pb.go @@ -14,6 +14,7 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" ) // This is a compile-time assertion to ensure that this generated file @@ -22,14 +23,20 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - ManagerService_Process_FullMethodName = "/manager.ManagerService/Process" + ManagerService_CreateVm_FullMethodName = "/manager.ManagerService/CreateVm" + ManagerService_RemoveVm_FullMethodName = "/manager.ManagerService/RemoveVm" + ManagerService_SVMInfo_FullMethodName = "/manager.ManagerService/SVMInfo" + ManagerService_AttestationPolicy_FullMethodName = "/manager.ManagerService/AttestationPolicy" ) // ManagerServiceClient is the client API for ManagerService service. // // 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 ManagerServiceClient interface { - Process(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ClientStreamMessage, ServerStreamMessage], error) + CreateVm(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateRes, error) + RemoveVm(ctx context.Context, in *RemoveReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + SVMInfo(ctx context.Context, in *SVMInfoReq, opts ...grpc.CallOption) (*SVMInfoRes, error) + AttestationPolicy(ctx context.Context, in *AttestationPolicyReq, opts ...grpc.CallOption) (*AttestationPolicyRes, error) } type managerServiceClient struct { @@ -40,24 +47,54 @@ func NewManagerServiceClient(cc grpc.ClientConnInterface) ManagerServiceClient { return &managerServiceClient{cc} } -func (c *managerServiceClient) Process(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ClientStreamMessage, ServerStreamMessage], error) { +func (c *managerServiceClient) CreateVm(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateRes, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &ManagerService_ServiceDesc.Streams[0], ManagerService_Process_FullMethodName, cOpts...) + out := new(CreateRes) + err := c.cc.Invoke(ctx, ManagerService_CreateVm_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } - x := &grpc.GenericClientStream[ClientStreamMessage, ServerStreamMessage]{ClientStream: stream} - return x, nil + return out, nil } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type ManagerService_ProcessClient = grpc.BidiStreamingClient[ClientStreamMessage, ServerStreamMessage] +func (c *managerServiceClient) RemoveVm(ctx context.Context, in *RemoveReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ManagerService_RemoveVm_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerServiceClient) SVMInfo(ctx context.Context, in *SVMInfoReq, opts ...grpc.CallOption) (*SVMInfoRes, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SVMInfoRes) + err := c.cc.Invoke(ctx, ManagerService_SVMInfo_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *managerServiceClient) AttestationPolicy(ctx context.Context, in *AttestationPolicyReq, opts ...grpc.CallOption) (*AttestationPolicyRes, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AttestationPolicyRes) + err := c.cc.Invoke(ctx, ManagerService_AttestationPolicy_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} // ManagerServiceServer is the server API for ManagerService service. // All implementations must embed UnimplementedManagerServiceServer // for forward compatibility. type ManagerServiceServer interface { - Process(grpc.BidiStreamingServer[ClientStreamMessage, ServerStreamMessage]) error + CreateVm(context.Context, *emptypb.Empty) (*CreateRes, error) + RemoveVm(context.Context, *RemoveReq) (*emptypb.Empty, error) + SVMInfo(context.Context, *SVMInfoReq) (*SVMInfoRes, error) + AttestationPolicy(context.Context, *AttestationPolicyReq) (*AttestationPolicyRes, error) mustEmbedUnimplementedManagerServiceServer() } @@ -68,8 +105,17 @@ type ManagerServiceServer interface { // pointer dereference when methods are called. type UnimplementedManagerServiceServer struct{} -func (UnimplementedManagerServiceServer) Process(grpc.BidiStreamingServer[ClientStreamMessage, ServerStreamMessage]) error { - return status.Errorf(codes.Unimplemented, "method Process not implemented") +func (UnimplementedManagerServiceServer) CreateVm(context.Context, *emptypb.Empty) (*CreateRes, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateVm not implemented") +} +func (UnimplementedManagerServiceServer) RemoveVm(context.Context, *RemoveReq) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveVm not implemented") +} +func (UnimplementedManagerServiceServer) SVMInfo(context.Context, *SVMInfoReq) (*SVMInfoRes, error) { + return nil, status.Errorf(codes.Unimplemented, "method SVMInfo not implemented") +} +func (UnimplementedManagerServiceServer) AttestationPolicy(context.Context, *AttestationPolicyReq) (*AttestationPolicyRes, error) { + return nil, status.Errorf(codes.Unimplemented, "method AttestationPolicy not implemented") } func (UnimplementedManagerServiceServer) mustEmbedUnimplementedManagerServiceServer() {} func (UnimplementedManagerServiceServer) testEmbeddedByValue() {} @@ -92,12 +138,77 @@ func RegisterManagerServiceServer(s grpc.ServiceRegistrar, srv ManagerServiceSer s.RegisterService(&ManagerService_ServiceDesc, srv) } -func _ManagerService_Process_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ManagerServiceServer).Process(&grpc.GenericServerStream[ClientStreamMessage, ServerStreamMessage]{ServerStream: stream}) +func _ManagerService_CreateVm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServiceServer).CreateVm(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ManagerService_CreateVm_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServiceServer).CreateVm(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) } -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type ManagerService_ProcessServer = grpc.BidiStreamingServer[ClientStreamMessage, ServerStreamMessage] +func _ManagerService_RemoveVm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServiceServer).RemoveVm(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ManagerService_RemoveVm_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServiceServer).RemoveVm(ctx, req.(*RemoveReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _ManagerService_SVMInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SVMInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServiceServer).SVMInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ManagerService_SVMInfo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServiceServer).SVMInfo(ctx, req.(*SVMInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _ManagerService_AttestationPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AttestationPolicyReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ManagerServiceServer).AttestationPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ManagerService_AttestationPolicy_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ManagerServiceServer).AttestationPolicy(ctx, req.(*AttestationPolicyReq)) + } + return interceptor(ctx, in, info, handler) +} // ManagerService_ServiceDesc is the grpc.ServiceDesc for ManagerService service. // It's only intended for direct use with grpc.RegisterService, @@ -105,14 +216,24 @@ type ManagerService_ProcessServer = grpc.BidiStreamingServer[ClientStreamMessage var ManagerService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "manager.ManagerService", HandlerType: (*ManagerServiceServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateVm", + Handler: _ManagerService_CreateVm_Handler, + }, + { + MethodName: "RemoveVm", + Handler: _ManagerService_RemoveVm_Handler, + }, + { + MethodName: "SVMInfo", + Handler: _ManagerService_SVMInfo_Handler, + }, { - StreamName: "Process", - Handler: _ManagerService_Process_Handler, - ServerStreams: true, - ClientStreams: true, + MethodName: "AttestationPolicy", + Handler: _ManagerService_AttestationPolicy_Handler, }, }, + Streams: []grpc.StreamDesc{}, Metadata: "manager/manager.proto", } diff --git a/manager/manager_test.go b/manager/manager_test.go deleted file mode 100644 index 5ff58c64..00000000 --- a/manager/manager_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package manager_test - -import ( - "bytes" - "context" - "testing" - - "github.com/ultravioletrs/cocos/manager" - "google.golang.org/grpc" - "google.golang.org/protobuf/proto" -) - -func TestProcess(t *testing.T) { - ctx := context.Background() - conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure()) - if err != nil { - t.Fatalf("Failed to dial bufnet: %v", err) - } - defer conn.Close() - - client := manager.NewManagerServiceClient(conn) - stream, err := client.Process(ctx) - if err != nil { - t.Fatalf("Process failed: %v", err) - } - - var data bytes.Buffer - for { - msg, err := stream.Recv() - if err != nil { - t.Fatalf("Failed to receive ServerStreamMessage: %v", err) - } - - switch m := msg.Message.(type) { - case *manager.ServerStreamMessage_TerminateReq: - if m.TerminateReq.Message != "test terminate" { - t.Fatalf("Unexpected terminate message: %v", m.TerminateReq.Message) - } - case *manager.ServerStreamMessage_RunReqChunks: - if len(m.RunReqChunks.Data) == 0 { - var runReq manager.ComputationRunReq - if err = proto.Unmarshal(data.Bytes(), &runReq); err != nil { - t.Fatalf("Failed to create run request: %v", err) - } - - runRes := &manager.ClientStreamMessage_AgentLog{ - AgentLog: &manager.AgentLog{ - Message: "test log", - ComputationId: "comp1", - Level: "DEBUG", - }, - } - if runReq.Id != "1" || runReq.Name != "sample computation" || runReq.Description != "sample description" { - t.Fatalf("Unexpected run request message: %v", &runReq) - } - if err := stream.Send(&manager.ClientStreamMessage{Message: runRes}); err != nil { - t.Fatalf("Failed to send ClientStreamMessage: %v", err) - } - return - } - data.Write(m.RunReqChunks.Data) - default: - t.Fatalf("Unexpected message type: %T", m) - } - } -} diff --git a/manager/mocks/service.go b/manager/mocks/service.go index 3fa06b38..a8bd94b2 100644 --- a/manager/mocks/service.go +++ b/manager/mocks/service.go @@ -9,7 +9,6 @@ import ( context "context" mock "github.com/stretchr/testify/mock" - manager "github.com/ultravioletrs/cocos/manager" ) // Service is an autogenerated mock type for the Service type @@ -25,6 +24,69 @@ func (_m *Service) EXPECT() *Service_Expecter { return &Service_Expecter{mock: &_m.Mock} } +// CreateVM provides a mock function with given fields: ctx +func (_m *Service) CreateVM(ctx context.Context) (string, string, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for CreateVM") + } + + var r0 string + var r1 string + var r2 error + if rf, ok := ret.Get(0).(func(context.Context) (string, string, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) string); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context) string); ok { + r1 = rf(ctx) + } else { + r1 = ret.Get(1).(string) + } + + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(ctx) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Service_CreateVM_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateVM' +type Service_CreateVM_Call struct { + *mock.Call +} + +// CreateVM is a helper method to define mock.On call +// - ctx context.Context +func (_e *Service_Expecter) CreateVM(ctx interface{}) *Service_CreateVM_Call { + return &Service_CreateVM_Call{Call: _e.mock.On("CreateVM", ctx)} +} + +func (_c *Service_CreateVM_Call) Run(run func(ctx context.Context)) *Service_CreateVM_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *Service_CreateVM_Call) Return(_a0 string, _a1 string, _a2 error) *Service_CreateVM_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *Service_CreateVM_Call) RunAndReturn(run func(context.Context) (string, string, error)) *Service_CreateVM_Call { + _c.Call.Return(run) + return _c +} + // FetchAttestationPolicy provides a mock function with given fields: ctx, computationID func (_m *Service) FetchAttestationPolicy(ctx context.Context, computationID string) ([]byte, error) { ret := _m.Called(ctx, computationID) @@ -84,35 +146,49 @@ func (_c *Service_FetchAttestationPolicy_Call) RunAndReturn(run func(context.Con return _c } -// ReportBrokenConnection provides a mock function with given fields: addr -func (_m *Service) ReportBrokenConnection(addr string) { - _m.Called(addr) +// RemoveVM provides a mock function with given fields: ctx, computationID +func (_m *Service) RemoveVM(ctx context.Context, computationID string) error { + ret := _m.Called(ctx, computationID) + + if len(ret) == 0 { + panic("no return value specified for RemoveVM") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, computationID) + } else { + r0 = ret.Error(0) + } + + return r0 } -// Service_ReportBrokenConnection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportBrokenConnection' -type Service_ReportBrokenConnection_Call struct { +// Service_RemoveVM_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveVM' +type Service_RemoveVM_Call struct { *mock.Call } -// ReportBrokenConnection is a helper method to define mock.On call -// - addr string -func (_e *Service_Expecter) ReportBrokenConnection(addr interface{}) *Service_ReportBrokenConnection_Call { - return &Service_ReportBrokenConnection_Call{Call: _e.mock.On("ReportBrokenConnection", addr)} +// RemoveVM is a helper method to define mock.On call +// - ctx context.Context +// - computationID string +func (_e *Service_Expecter) RemoveVM(ctx interface{}, computationID interface{}) *Service_RemoveVM_Call { + return &Service_RemoveVM_Call{Call: _e.mock.On("RemoveVM", ctx, computationID)} } -func (_c *Service_ReportBrokenConnection_Call) Run(run func(addr string)) *Service_ReportBrokenConnection_Call { +func (_c *Service_RemoveVM_Call) Run(run func(ctx context.Context, computationID string)) *Service_RemoveVM_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(context.Context), args[1].(string)) }) return _c } -func (_c *Service_ReportBrokenConnection_Call) Return() *Service_ReportBrokenConnection_Call { - _c.Call.Return() +func (_c *Service_RemoveVM_Call) Return(_a0 error) *Service_RemoveVM_Call { + _c.Call.Return(_a0) return _c } -func (_c *Service_ReportBrokenConnection_Call) RunAndReturn(run func(string)) *Service_ReportBrokenConnection_Call { +func (_c *Service_RemoveVM_Call) RunAndReturn(run func(context.Context, string) error) *Service_RemoveVM_Call { _c.Call.Return(run) return _c } @@ -187,110 +263,6 @@ func (_c *Service_ReturnSVMInfo_Call) RunAndReturn(run func(context.Context) (st return _c } -// Run provides a mock function with given fields: ctx, c -func (_m *Service) Run(ctx context.Context, c *manager.ComputationRunReq) (string, error) { - ret := _m.Called(ctx, c) - - if len(ret) == 0 { - panic("no return value specified for Run") - } - - var r0 string - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *manager.ComputationRunReq) (string, error)); ok { - return rf(ctx, c) - } - if rf, ok := ret.Get(0).(func(context.Context, *manager.ComputationRunReq) string); ok { - r0 = rf(ctx, c) - } else { - r0 = ret.Get(0).(string) - } - - if rf, ok := ret.Get(1).(func(context.Context, *manager.ComputationRunReq) error); ok { - r1 = rf(ctx, c) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Service_Run_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Run' -type Service_Run_Call struct { - *mock.Call -} - -// Run is a helper method to define mock.On call -// - ctx context.Context -// - c *manager.ComputationRunReq -func (_e *Service_Expecter) Run(ctx interface{}, c interface{}) *Service_Run_Call { - return &Service_Run_Call{Call: _e.mock.On("Run", ctx, c)} -} - -func (_c *Service_Run_Call) Run(run func(ctx context.Context, c *manager.ComputationRunReq)) *Service_Run_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*manager.ComputationRunReq)) - }) - return _c -} - -func (_c *Service_Run_Call) Return(_a0 string, _a1 error) *Service_Run_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *Service_Run_Call) RunAndReturn(run func(context.Context, *manager.ComputationRunReq) (string, error)) *Service_Run_Call { - _c.Call.Return(run) - return _c -} - -// Stop provides a mock function with given fields: ctx, computationID -func (_m *Service) Stop(ctx context.Context, computationID string) error { - ret := _m.Called(ctx, computationID) - - if len(ret) == 0 { - panic("no return value specified for Stop") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = rf(ctx, computationID) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Service_Stop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stop' -type Service_Stop_Call struct { - *mock.Call -} - -// Stop is a helper method to define mock.On call -// - ctx context.Context -// - computationID string -func (_e *Service_Expecter) Stop(ctx interface{}, computationID interface{}) *Service_Stop_Call { - return &Service_Stop_Call{Call: _e.mock.On("Stop", ctx, computationID)} -} - -func (_c *Service_Stop_Call) Run(run func(ctx context.Context, computationID string)) *Service_Stop_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *Service_Stop_Call) Return(_a0 error) *Service_Stop_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *Service_Stop_Call) RunAndReturn(run func(context.Context, string) error) *Service_Stop_Call { - _c.Call.Return(run) - return _c -} - // NewService creates a new instance of Service. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewService(t interface { diff --git a/manager/qemu/vm.go b/manager/qemu/vm.go index c54ce4ad..870ac6f3 100644 --- a/manager/qemu/vm.go +++ b/manager/qemu/vm.go @@ -13,7 +13,6 @@ import ( "github.com/ultravioletrs/cocos/internal" "github.com/ultravioletrs/cocos/manager/vm" "github.com/ultravioletrs/cocos/pkg/manager" - "google.golang.org/protobuf/types/known/timestamppb" ) const ( @@ -31,19 +30,17 @@ type VMInfo struct { } type qemuVM struct { - vmi VMInfo - cmd *exec.Cmd - eventsLogsSender vm.EventSender - computationId string + vmi VMInfo + cmd *exec.Cmd + computationId string vm.StateMachine } -func NewVM(config interface{}, eventsLogsSender vm.EventSender, computationId string) vm.VM { +func NewVM(config interface{}, computationId string) vm.VM { return &qemuVM{ - vmi: config.(VMInfo), - eventsLogsSender: eventsLogsSender, - computationId: computationId, - StateMachine: vm.NewStateMachine(), + vmi: config.(VMInfo), + computationId: computationId, + StateMachine: vm.NewStateMachine(), } } @@ -79,8 +76,8 @@ func (v *qemuVM) Start() (err error) { } v.cmd = exec.Command(exe, args...) - v.cmd.Stdout = &vm.Stdout{ComputationId: v.computationId, EventSender: v.eventsLogsSender} - v.cmd.Stderr = &vm.Stderr{EventSender: v.eventsLogsSender, ComputationId: v.computationId, StateMachine: v.StateMachine} + v.cmd.Stdout = os.Stdout + v.cmd.Stderr = os.Stderr return v.cmd.Start() } @@ -89,15 +86,7 @@ func (v *qemuVM) Stop() error { defer func() { err := v.StateMachine.Transition(manager.StopComputationRun) if err != nil { - if err := v.eventsLogsSender(&vm.Event{ - EventType: v.StateMachine.State(), - Timestamp: timestamppb.Now(), - ComputationId: v.computationId, - Originator: "manager", - Status: manager.Warning.String(), - }); err != nil { - return - } + return } }() err := v.cmd.Process.Signal(syscall.SIGTERM) @@ -163,15 +152,6 @@ func (v *qemuVM) executableAndArgs() (string, []string, error) { func (v *qemuVM) checkVMProcessPeriodically() { for { if !processExists(v.GetProcess()) { - if err := v.eventsLogsSender(&vm.Event{ - EventType: v.StateMachine.State(), - Timestamp: timestamppb.Now(), - ComputationId: v.computationId, - Originator: "manager", - Status: manager.Stopped.String(), - }); err != nil { - return - } break } time.Sleep(interval) diff --git a/manager/qemu/vm_test.go b/manager/qemu/vm_test.go index 4d28c05c..2327c3fc 100644 --- a/manager/qemu/vm_test.go +++ b/manager/qemu/vm_test.go @@ -6,10 +6,8 @@ import ( "os" "os/exec" "testing" - "time" "github.com/stretchr/testify/assert" - "github.com/ultravioletrs/cocos/manager/vm" "github.com/ultravioletrs/cocos/manager/vm/mocks" pkgmanager "github.com/ultravioletrs/cocos/pkg/manager" ) @@ -19,7 +17,7 @@ const testComputationID = "test-computation" func TestNewVM(t *testing.T) { config := VMInfo{Config: Config{}} - vm := NewVM(config, func(event interface{}) error { return nil }, testComputationID) + vm := NewVM(config, testComputationID) assert.NotNil(t, vm) assert.IsType(t, &qemuVM{}, vm) @@ -38,7 +36,7 @@ func TestStart(t *testing.T) { QemuBinPath: "echo", }} - vm := NewVM(config, func(event interface{}) error { return nil }, testComputationID).(*qemuVM) + vm := NewVM(config, testComputationID).(*qemuVM) err = vm.Start() assert.NoError(t, err) @@ -61,7 +59,7 @@ func TestStartSudo(t *testing.T) { UseSudo: true, }} - vm := NewVM(config, func(event interface{}) error { return nil }, testComputationID).(*qemuVM) + vm := NewVM(config, testComputationID).(*qemuVM) err = vm.Start() assert.NoError(t, err) @@ -101,9 +99,6 @@ func TestStop(t *testing.T) { Process: cmd.Process, }, StateMachine: sm, - eventsLogsSender: func(event interface{}) error { - return nil - }, } err = vm.Stop() @@ -165,31 +160,3 @@ func TestGetConfig(t *testing.T) { config := vm.GetConfig() assert.Equal(t, expectedConfig, config) } - -func TestCheckVMProcessPeriodically(t *testing.T) { - logsChan := make(chan interface{}, 1) - vmi := &qemuVM{ - eventsLogsSender: func(event interface{}) error { - logsChan <- event - return nil - }, - computationId: testComputationID, - cmd: &exec.Cmd{ - Process: &os.Process{Pid: -1}, // Use an invalid PID to simulate a stopped process - }, - StateMachine: vm.NewStateMachine(), - } - - go vmi.checkVMProcessPeriodically() - - select { - case msg := <-logsChan: - assert.NotNil(t, msg) - msgE := msg.(*vm.Event) - assert.Equal(t, testComputationID, msgE.ComputationId) - assert.Equal(t, pkgmanager.VmProvision.String(), msgE.EventType) - assert.Equal(t, pkgmanager.Stopped.String(), msgE.Status) - case <-time.After(2 * interval): - t.Fatal("Timeout waiting for VM stopped message") - } -} diff --git a/manager/service.go b/manager/service.go index 31e53853..1221a44d 100644 --- a/manager/service.go +++ b/manager/service.go @@ -5,7 +5,6 @@ package manager import ( "context" "encoding/base64" - "encoding/json" "fmt" "log/slog" "net" @@ -17,15 +16,13 @@ import ( "syscall" "github.com/absmach/magistrala/pkg/errors" - "github.com/cenkalti/backoff/v4" "github.com/google/go-sev-guest/proto/check" - "github.com/ultravioletrs/cocos/agent" + "github.com/google/uuid" "github.com/ultravioletrs/cocos/manager/qemu" "github.com/ultravioletrs/cocos/manager/vm" "github.com/ultravioletrs/cocos/pkg/manager" "golang.org/x/crypto/sha3" "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/types/known/timestamppb" ) const ( @@ -48,8 +45,6 @@ var ( // ErrFailedToAllocatePort indicates no free port was found on host. ErrFailedToAllocatePort = errors.New("failed to allocate free port on host") - errInvalidHashLength = errors.New("hash must be of byte length 32") - // ErrFailedToCalculateHash indicates that agent computation returned an error while calculating the hash of the computation. ErrFailedToCalculateHash = errors.New("error while calculating the hash of the computation") @@ -67,13 +62,11 @@ var ( // implementation, and all of its decorators (e.g. logging & metrics). type Service interface { // Run create a computation. - Run(ctx context.Context, c *ComputationRunReq) (string, error) + CreateVM(ctx context.Context) (string, string, error) // Stop stops a computation. - Stop(ctx context.Context, computationID string) error + RemoveVM(ctx context.Context, computationID string) error // FetchAttestationPolicy measures and fetches the attestation policy. FetchAttestationPolicy(ctx context.Context, computationID string) ([]byte, error) - // ReportBrokenConnection reports a broken connection. - ReportBrokenConnection(addr string) // ReturnSVMInfo returns SVM information needed for attestation verification and validation. ReturnSVMInfo(ctx context.Context) (string, int, string, string) } @@ -84,7 +77,6 @@ type managerService struct { qemuCfg qemu.Config attestationPolicyBinaryPath string logger *slog.Logger - eventsChan chan *ClientStreamMessage vms map[string]vm.VM vmFactory vm.Provider portRangeMin int @@ -96,7 +88,7 @@ type managerService struct { var _ Service = (*managerService)(nil) // New instantiates the manager service implementation. -func New(cfg qemu.Config, attestationPolicyBinPath string, logger *slog.Logger, eventsChan chan *ClientStreamMessage, vmFactory vm.Provider, eosVersion string) (Service, error) { +func New(cfg qemu.Config, attestationPolicyBinPath string, logger *slog.Logger, vmFactory vm.Provider, eosVersion string) (Service, error) { start, end, err := decodeRange(cfg.HostFwdRange) if err != nil { return nil, err @@ -111,7 +103,6 @@ func New(cfg qemu.Config, attestationPolicyBinPath string, logger *slog.Logger, qemuCfg: cfg, logger: logger, vms: make(map[string]vm.VM), - eventsChan: eventsChan, vmFactory: vmFactory, attestationPolicyBinaryPath: attestationPolicyBinPath, portRangeMin: start, @@ -127,7 +118,8 @@ func New(cfg qemu.Config, attestationPolicyBinPath string, logger *slog.Logger, return ms, nil } -func (ms *managerService) Run(ctx context.Context, c *ComputationRunReq) (string, error) { +func (ms *managerService) CreateVM(ctx context.Context) (string, string, error) { + id := uuid.New().String() ms.mu.Lock() cfg := qemu.VMInfo{ Config: ms.qemuCfg, @@ -142,54 +134,29 @@ func (ms *managerService) Run(ctx context.Context, c *ComputationRunReq) (string _, err := cmd.Output() ms.ap.Unlock() if err != nil { - return "", errors.Wrap(ErrFailedToCreateAttestationPolicy, err) + return "", id, errors.Wrap(ErrFailedToCreateAttestationPolicy, err) } ms.ap.Lock() f, err := os.ReadFile("./attestation_policy.json") ms.ap.Unlock() if err != nil { - return "", errors.Wrap(ErrFailedToReadPolicy, err) + return "", id, errors.Wrap(ErrFailedToReadPolicy, err) } var attestationPolicy check.Config if err = protojson.Unmarshal(f, &attestationPolicy); err != nil { - return "", errors.Wrap(ErrUnmarshalFailed, err) + return "", id, errors.Wrap(ErrUnmarshalFailed, err) } // Define the TCB that was present at launch of the VM. cfg.LaunchTCB = attestationPolicy.Policy.MinimumLaunchTcb } - ms.publishEvent(manager.VmProvision.String(), c.Id, manager.Starting.String(), json.RawMessage{}) - ac := agent.Computation{ - ID: c.Id, - Name: c.Name, - Description: c.Description, - } - if len(c.Algorithm.Hash) != hashLength { - ms.publishEvent(manager.VmProvision.String(), c.Id, agent.Failed.String(), json.RawMessage{}) - return "", errInvalidHashLength - } - - ac.Algorithm = agent.Algorithm{Hash: [hashLength]byte(c.Algorithm.Hash), UserKey: c.Algorithm.UserKey} - - for _, data := range c.Datasets { - if len(data.Hash) != hashLength { - ms.publishEvent(manager.VmProvision.String(), c.Id, agent.Failed.String(), json.RawMessage{}) - return "", errInvalidHashLength - } - ac.Datasets = append(ac.Datasets, agent.Dataset{Hash: [hashLength]byte(data.Hash), UserKey: data.UserKey, Filename: data.Filename}) - } - - for _, rc := range c.ResultConsumers { - ac.ResultConsumers = append(ac.ResultConsumers, agent.ResultConsumer{UserKey: rc.UserKey}) - } agentPort, err := getFreePort(ms.portRangeMin, ms.portRangeMax) if err != nil { - ms.publishEvent(manager.VmProvision.String(), c.Id, agent.Failed.String(), json.RawMessage{}) - return "", errors.Wrap(ErrFailedToAllocatePort, err) + return "", id, errors.Wrap(ErrFailedToAllocatePort, err) } cfg.Config.HostFwdAgent = agentPort @@ -210,30 +177,23 @@ func (ms *managerService) Run(ctx context.Context, c *ComputationRunReq) (string cfg.Config.VSockConfig.GuestCID = cid if cfg.Config.EnableSEVSNP { - ch, err := computationHash(ac) - if err != nil { - ms.publishEvent(manager.VmProvision.String(), c.Id, agent.Failed.String(), json.RawMessage{}) - return "", errors.Wrap(ErrFailedToCalculateHash, err) - } - + todo := sha3.Sum256([]byte("TODO")) // Define host-data value of QEMU for SEV-SNP, with a base64 encoding of the computation hash. - cfg.Config.SevConfig.HostData = base64.StdEncoding.EncodeToString(ch[:]) + cfg.Config.SevConfig.HostData = base64.StdEncoding.EncodeToString(todo[:]) } - cvm := ms.vmFactory(cfg, ms.eventsLogsSender, c.Id) - ms.publishEvent(manager.VmProvision.String(), c.Id, agent.InProgress.String(), json.RawMessage{}) + cvm := ms.vmFactory(cfg, id) if err = cvm.Start(); err != nil { - ms.publishEvent(manager.VmProvision.String(), c.Id, agent.Failed.String(), json.RawMessage{}) - return "", err + return "", id, err } ms.mu.Lock() - ms.vms[c.Id] = cvm + ms.vms[id] = cvm ms.mu.Unlock() pid := cvm.GetProcess() state := qemu.VMState{ - ID: c.Id, + ID: id, VMinfo: cfg, PID: pid, } @@ -241,34 +201,23 @@ func (ms *managerService) Run(ctx context.Context, c *ComputationRunReq) (string ms.logger.Error("Failed to persist VM state", "error", err) } - err = backoff.Retry(func() error { - return cvm.SendAgentConfig(ac) - }, backoff.NewExponentialBackOff()) - if err != nil { - return "", err - } - ms.mu.Lock() - if err := ms.vms[c.Id].Transition(manager.VmRunning); err != nil { - ms.logger.Warn("Failed to transition VM state", "computation", c.Id, "error", err) + if err := ms.vms[id].Transition(manager.VmRunning); err != nil { + ms.logger.Warn("Failed to transition VM state", "cvm", id, "error", err) } ms.mu.Unlock() - ms.publishEvent(manager.VmProvision.String(), c.Id, agent.Completed.String(), json.RawMessage{}) - - return fmt.Sprint(agentPort), nil + return fmt.Sprint(agentPort), id, nil } -func (ms *managerService) Stop(ctx context.Context, computationID string) error { +func (ms *managerService) RemoveVM(ctx context.Context, computationID string) error { ms.mu.Lock() defer ms.mu.Unlock() cvm, ok := ms.vms[computationID] if !ok { - defer ms.publishEvent(manager.StopComputationRun.String(), computationID, agent.Failed.String(), json.RawMessage{}) return ErrNotFound } if err := cvm.Stop(); err != nil { - defer ms.publishEvent(manager.StopComputationRun.String(), computationID, agent.Failed.String(), json.RawMessage{}) return err } delete(ms.vms, computationID) @@ -277,7 +226,6 @@ func (ms *managerService) Stop(ctx context.Context, computationID string) error ms.logger.Error("Failed to delete persisted VM state", "error", err) } - defer ms.publishEvent(manager.StopComputationRun.String(), computationID, agent.Completed.String(), json.RawMessage{}) return nil } @@ -329,30 +277,6 @@ func checkPortisFree(port int) bool { return true } -func (ms *managerService) publishEvent(event, cmpID, status string, details json.RawMessage) { - ms.eventsChan <- &ClientStreamMessage{ - Message: &ClientStreamMessage_AgentEvent{ - AgentEvent: &AgentEvent{ - EventType: event, - ComputationId: cmpID, - Status: status, - Details: details, - Timestamp: timestamppb.Now(), - Originator: "manager", - }, - }, - } -} - -func computationHash(ac agent.Computation) ([32]byte, error) { - jsonData, err := json.Marshal(ac) - if err != nil { - return [32]byte{}, err - } - - return sha3.Sum256(jsonData), nil -} - func decodeRange(input string) (int, int, error) { re := regexp.MustCompile(`(\d+)-(\d+)`) matches := re.FindStringSubmatch(input) @@ -392,7 +316,7 @@ func (ms *managerService) restoreVMs() error { continue } - cvm := ms.vmFactory(state.VMinfo, ms.eventsLogsSender, state.ID) + cvm := ms.vmFactory(state.VMinfo, state.ID) if err = cvm.SetProcess(state.PID); err != nil { ms.logger.Warn("Failed to reattach to process", "computation", state.ID, "pid", state.PID, "error", err) @@ -425,33 +349,3 @@ func (ms *managerService) processExists(pid int) bool { } return false } - -func (ms *managerService) eventsLogsSender(e interface{}) error { - switch msg := e.(type) { - case *vm.Event: - ms.eventsChan <- &ClientStreamMessage{ - Message: &ClientStreamMessage_AgentEvent{ - AgentEvent: &AgentEvent{ - EventType: msg.EventType, - Timestamp: msg.Timestamp, - ComputationId: msg.ComputationId, - Originator: msg.Originator, - Status: msg.Status, - Details: msg.Details, - }, - }, - } - case *vm.Log: - ms.eventsChan <- &ClientStreamMessage{ - Message: &ClientStreamMessage_AgentLog{ - AgentLog: &AgentLog{ - ComputationId: msg.ComputationId, - Level: msg.Level, - Timestamp: msg.Timestamp, - Message: msg.Message, - }, - }, - } - } - return nil -} diff --git a/manager/service_test.go b/manager/service_test.go index 3814f1e4..9809b88b 100644 --- a/manager/service_test.go +++ b/manager/service_test.go @@ -4,7 +4,6 @@ package manager import ( "context" - "encoding/json" "fmt" "log/slog" "net" @@ -17,7 +16,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/ultravioletrs/cocos/agent" "github.com/ultravioletrs/cocos/manager/qemu" persistenceMocks "github.com/ultravioletrs/cocos/manager/qemu/mocks" "github.com/ultravioletrs/cocos/manager/vm" @@ -29,10 +27,9 @@ func TestNew(t *testing.T) { HostFwdRange: "6000-6100", } logger := slog.Default() - eventsChan := make(chan *ClientStreamMessage) vmf := new(mocks.Provider) - service, err := New(cfg, "", logger, eventsChan, vmf.Execute, "") + service, err := New(cfg, "", logger, vmf.Execute, "") require.NoError(t, err) assert.NotNil(t, service) @@ -46,82 +43,24 @@ func TestRun(t *testing.T) { vmf.On("Execute", mock.Anything, mock.Anything, mock.Anything).Return(vmMock) tests := []struct { name string - req *ComputationRunReq binaryBehavior string vmStartError error expectedError error }{ { - name: "Successful run", - req: &ComputationRunReq{ - Id: "test-computation", - Name: "Test Computation", - Algorithm: &Algorithm{ - Hash: make([]byte, hashLength), - }, - AgentConfig: &AgentConfig{}, - }, + name: "Successful run", binaryBehavior: "success", vmStartError: nil, expectedError: nil, }, { - name: "VM start failure", - req: &ComputationRunReq{ - Id: "test-computation", - Name: "Test Computation", - Algorithm: &Algorithm{ - Hash: make([]byte, hashLength), - }, - AgentConfig: &AgentConfig{}, - }, + name: "VM start failure", binaryBehavior: "success", vmStartError: assert.AnError, expectedError: assert.AnError, }, { - name: "Invalid algorithm hash", - req: &ComputationRunReq{ - Id: "test-computation", - Name: "Test Computation", - Algorithm: &Algorithm{ - Hash: make([]byte, hashLength-1), - }, - AgentConfig: &AgentConfig{}, - }, - binaryBehavior: "success", - vmStartError: nil, - expectedError: errInvalidHashLength, - }, - { - name: "Invalid dataset hash", - req: &ComputationRunReq{ - Id: "test-computation", - Name: "Test Computation", - Algorithm: &Algorithm{ - Hash: make([]byte, hashLength), - }, - AgentConfig: &AgentConfig{}, - Datasets: []*Dataset{ - { - Hash: make([]byte, hashLength-1), - }, - }, - }, - binaryBehavior: "success", - vmStartError: nil, - expectedError: errInvalidHashLength, - }, - { - name: "Invalid attestation policy", - req: &ComputationRunReq{ - Id: "test-computation", - Name: "Test Computation", - Algorithm: &Algorithm{ - Hash: make([]byte, hashLength), - }, - AgentConfig: &AgentConfig{}, - }, + name: "Invalid attestation policy", binaryBehavior: "fail", vmStartError: nil, expectedError: ErrFailedToCreateAttestationPolicy, @@ -149,7 +88,6 @@ func TestRun(t *testing.T) { }, } logger := slog.Default() - eventsChan := make(chan *ClientStreamMessage, 10) tempDir := CreateDummyAttestationPolicyBinary(t, tt.binaryBehavior) defer os.RemoveAll(tempDir) @@ -159,14 +97,13 @@ func TestRun(t *testing.T) { attestationPolicyBinaryPath: tempDir, logger: logger, vms: make(map[string]vm.VM), - eventsChan: eventsChan, vmFactory: vmf.Execute, persistence: persistence, } ctx := context.Background() - port, err := ms.Run(ctx, tt.req) + port, _, err := ms.CreateVM(ctx) if tt.expectedError != nil { assert.Error(t, err) @@ -179,10 +116,6 @@ func TestRun(t *testing.T) { } vmf.AssertExpectations(t) - - for len(eventsChan) > 0 { - <-eventsChan - } }) } } @@ -226,11 +159,9 @@ func TestStop(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { logger := slog.Default() - eventsChan := make(chan *ClientStreamMessage, 10) ms := &managerService{ logger: logger, vms: make(map[string]vm.VM), - eventsChan: eventsChan, persistence: persistence, } vmMock := new(mocks.VM) @@ -247,7 +178,7 @@ func TestStop(t *testing.T) { ms.vms[tt.computationID] = vmMock } - err := ms.Stop(context.Background(), tt.computationID) + err := ms.RemoveVM(context.Background(), tt.computationID) if tt.expectedError != nil { assert.Error(t, err) @@ -256,10 +187,6 @@ func TestStop(t *testing.T) { assert.NoError(t, err) assert.Len(t, ms.vms, 0) } - - for len(eventsChan) > 0 { - <-eventsChan - } }) } } @@ -278,82 +205,6 @@ func TestGetFreePort(t *testing.T) { assert.Greater(t, port, 6000) } -func TestPublishEvent(t *testing.T) { - tests := []struct { - name string - event string - computationID string - status string - details json.RawMessage - }{ - { - name: "Standard event", - event: "test-event", - computationID: "test-computation", - status: "test-status", - details: nil, - }, - { - name: "Event with details", - event: "detailed-event", - computationID: "detailed-computation", - status: "detailed-status", - details: json.RawMessage(`{"key": "value"}`), - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - eventsChan := make(chan *ClientStreamMessage, 1) - ms := &managerService{ - eventsChan: eventsChan, - } - - ms.publishEvent(tt.event, tt.computationID, tt.status, tt.details) - - assert.Len(t, eventsChan, 1) - event := <-eventsChan - assert.Equal(t, tt.event, event.GetAgentEvent().EventType) - assert.Equal(t, tt.computationID, event.GetAgentEvent().ComputationId) - assert.Equal(t, tt.status, event.GetAgentEvent().Status) - assert.Equal(t, "manager", event.GetAgentEvent().Originator) - assert.Equal(t, tt.details, json.RawMessage(event.GetAgentEvent().Details)) - }) - } -} - -func TestComputationHash(t *testing.T) { - tests := []struct { - name string - computation agent.Computation - wantErr bool - }{ - { - name: "Valid computation", - computation: agent.Computation{ - ID: "test-id", - Name: "test-name", - }, - wantErr: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - hash, err := computationHash(tt.computation) - if tt.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - assert.NotEmpty(t, hash) - - hash2, _ := computationHash(tt.computation) - assert.Equal(t, hash, hash2) - } - }) - } -} - func TestDecodeRange(t *testing.T) { tests := []struct { name string @@ -393,7 +244,6 @@ func TestRestoreVMs(t *testing.T) { ms := &managerService{ persistence: mockPersistence, vms: make(map[string]vm.VM), - eventsChan: make(chan *ClientStreamMessage, 10), vmFactory: vmf.Execute, logger: mglog.NewMock(), } diff --git a/manager/setup_test.go b/manager/setup_test.go deleted file mode 100644 index 07c1c50d..00000000 --- a/manager/setup_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package manager_test - -import ( - "context" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "log/slog" - "net" - "os" - "testing" - "time" - - mglog "github.com/absmach/magistrala/logger" - "github.com/ultravioletrs/cocos/manager" - managergrpc "github.com/ultravioletrs/cocos/manager/api/grpc" - "golang.org/x/crypto/sha3" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/test/bufconn" -) - -const ( - bufSize = 1024 * 1024 - keyBitSize = 4096 -) - -var ( - lis *bufconn.Listener - algoPath = "../test/manual/algo/lin_reg.py" - dataPath = "../test/manual/data/iris.csv" - attestedTLS = false -) - -type svc struct { - logger *slog.Logger - t *testing.T -} - -func TestMain(m *testing.M) { - logger := mglog.NewMock() - - lis = bufconn.Listen(bufSize) - s := grpc.NewServer() - - manager.RegisterManagerServiceServer(s, managergrpc.NewServer(make(chan *manager.ClientStreamMessage, 1), &svc{logger: logger})) - go func() { - if err := s.Serve(lis); err != nil { - panic(err) - } - }() - - code := m.Run() - - s.Stop() - lis.Close() - os.Exit(code) -} - -func bufDialer(context.Context, string) (net.Conn, error) { - return lis.Dial() -} - -func (s *svc) Run(ctx context.Context, ipAddress string, sendMessage managergrpc.SendFunc, authInfo credentials.AuthInfo) { - privKey, err := rsa.GenerateKey(rand.Reader, keyBitSize) - if err != nil { - s.t.Fatalf("Error generating public key: %v", err) - } - - pubKey, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey) - if err != nil { - s.t.Fatalf("Error marshalling public key: %v", err) - } - - pubPemBytes := pem.EncodeToMemory(&pem.Block{ - Type: "PUBLIC KEY", - Bytes: pubKey, - }) - - go func() { - time.Sleep(time.Millisecond * 100) - if err := sendMessage(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_TerminateReq{ - TerminateReq: &manager.Terminate{Message: "test terminate"}, - }, - }); err != nil { - s.t.Fatalf("failed to send terminate request: %s", err) - } - }() - - go func() { - time.Sleep(time.Millisecond * 100) - algo, err := os.ReadFile(algoPath) - if err != nil { - s.t.Fatalf("failed to read algorithm file: %s", err) - return - } - data, err := os.ReadFile(dataPath) - if err != nil { - s.t.Fatalf("failed to read data file: %s", err) - return - } - - pubPem, _ := pem.Decode(pubPemBytes) - algoHash := sha3.Sum256(algo) - dataHash := sha3.Sum256(data) - - if err := sendMessage(&manager.ServerStreamMessage{ - Message: &manager.ServerStreamMessage_RunReq{ - RunReq: &manager.ComputationRunReq{ - Id: "1", - Name: "sample computation", - Description: "sample description", - Datasets: []*manager.Dataset{{Hash: dataHash[:], UserKey: pubPem.Bytes}}, - Algorithm: &manager.Algorithm{Hash: algoHash[:], UserKey: pubPem.Bytes}, - ResultConsumers: []*manager.ResultConsumer{{UserKey: pubPem.Bytes}}, - AgentConfig: &manager.AgentConfig{ - Port: "7002", - LogLevel: "debug", - AttestedTls: attestedTLS, - }, - }, - }, - }); err != nil { - s.t.Fatalf("failed to send run request: %s", err) - } - }() -} diff --git a/manager/tracing/tracing.go b/manager/tracing/tracing.go index 322d1767..5be5c199 100644 --- a/manager/tracing/tracing.go +++ b/manager/tracing/tracing.go @@ -21,18 +21,18 @@ func New(svc manager.Service, tracer trace.Tracer) manager.Service { return &tracingMiddleware{tracer, svc} } -func (tm *tracingMiddleware) Run(ctx context.Context, mc *manager.ComputationRunReq) (string, error) { +func (tm *tracingMiddleware) CreateVM(ctx context.Context) (string, string, error) { ctx, span := tm.tracer.Start(ctx, "run") defer span.End() - return tm.svc.Run(ctx, mc) + return tm.svc.CreateVM(ctx) } -func (tm *tracingMiddleware) Stop(ctx context.Context, computationID string) error { +func (tm *tracingMiddleware) RemoveVM(ctx context.Context, id string) error { ctx, span := tm.tracer.Start(ctx, "stop") defer span.End() - return tm.svc.Stop(ctx, computationID) + return tm.svc.RemoveVM(ctx, id) } func (tm *tracingMiddleware) FetchAttestationPolicy(ctx context.Context, computationId string) ([]byte, error) { @@ -42,10 +42,6 @@ func (tm *tracingMiddleware) FetchAttestationPolicy(ctx context.Context, computa return tm.svc.FetchAttestationPolicy(ctx, computationId) } -func (tm *tracingMiddleware) ReportBrokenConnection(addr string) { - tm.svc.ReportBrokenConnection(addr) -} - func (tm *tracingMiddleware) ReturnSVMInfo(ctx context.Context) (string, int, string, string) { _, span := tm.tracer.Start(ctx, "return_svm_info") defer span.End() diff --git a/manager/vm/logging.go b/manager/vm/logging.go deleted file mode 100644 index 8e91e959..00000000 --- a/manager/vm/logging.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package vm - -import ( - "bytes" - "io" - "log/slog" - "strings" - - pkgmanager "github.com/ultravioletrs/cocos/pkg/manager" - "google.golang.org/protobuf/types/known/timestamppb" -) - -var ( - _ io.Writer = &Stdout{} - _ io.Writer = &Stderr{} -) - -const bufSize = 1024 - -type Stdout struct { - EventSender EventSender - ComputationId string -} - -// Write implements io.Writer. -func (s *Stdout) Write(p []byte) (n int, err error) { - inBuf := bytes.NewBuffer(p) - - buf := make([]byte, bufSize) - - for { - n, err := inBuf.Read(buf) - if err != nil { - if err == io.EOF { - break - } - return len(p) - inBuf.Len(), err - } - - if err := sendLog(s.EventSender, s.ComputationId, string(buf[:n]), slog.LevelDebug.String()); err != nil { - return len(p) - inBuf.Len(), err - } - } - - return len(p), nil -} - -type Stderr struct { - EventSender EventSender - ComputationId string - StateMachine StateMachine -} - -// Write implements io.Writer. -func (s *Stderr) Write(p []byte) (n int, err error) { - inBuf := bytes.NewBuffer(p) - - buf := make([]byte, bufSize) - - for { - n, err := inBuf.Read(buf) - if err != nil { - if err == io.EOF { - break - } - return len(p) - inBuf.Len(), err - } - - if err := sendLog(s.EventSender, s.ComputationId, string(buf[:n]), ""); err != nil { - return len(p) - inBuf.Len(), err - } - } - - eventMsg := &Event{ - ComputationId: s.ComputationId, - EventType: s.StateMachine.State(), - Timestamp: timestamppb.Now(), - Originator: "manager", - Status: pkgmanager.Warning.String(), - } - - return len(p), s.EventSender(eventMsg) -} - -func sendLog(eventSender EventSender, computationID, message, level string) error { - if len(message) < 3 { - return nil - } - - if level == "" { - if strings.Contains(strings.ToLower(message), "warning") { - level = slog.LevelWarn.String() - } else { - level = slog.LevelError.String() - } - } - - msg := Log{ - Message: message, - ComputationId: computationID, - Level: level, - Timestamp: timestamppb.Now(), - } - - return eventSender(&msg) -} diff --git a/manager/vm/logging_test.go b/manager/vm/logging_test.go deleted file mode 100644 index fbcbf9d4..00000000 --- a/manager/vm/logging_test.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) Ultraviolet -// SPDX-License-Identifier: Apache-2.0 -package vm - -import ( - "log/slog" - "testing" - "time" - - "github.com/stretchr/testify/assert" - pkgmanager "github.com/ultravioletrs/cocos/pkg/manager" -) - -func TestStdoutWrite(t *testing.T) { - tests := []struct { - name string - input string - expectedWrites int - }{ - { - name: "Single write within buffer size", - input: "Hello, World!", - expectedWrites: 1, - }, - { - name: "Multiple writes within buffer size", - input: "This is a longer message that will be split into multiple writes.", - expectedWrites: 1, - }, - { - name: "Large write exceeding buffer size", - input: string(make([]byte, bufSize*2+3)), - expectedWrites: 3, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - eventLogChan := make(chan interface{}, 10) - s := &Stdout{ - EventSender: func(event interface{}) error { - eventLogChan <- event - return nil - }, - ComputationId: "test-computation", - } - - n, err := s.Write([]byte(tt.input)) - - assert.NoError(t, err) - assert.Equal(t, len(tt.input), n) - - var receivedWrites int - for i := 0; i < tt.expectedWrites; i++ { - select { - case msg := <-eventLogChan: - receivedWrites++ - agentLog := msg.(*Log) - assert.NotNil(t, agentLog) - assert.Equal(t, "test-computation", agentLog.ComputationId) - assert.Equal(t, slog.LevelDebug.String(), agentLog.Level) - assert.NotEmpty(t, agentLog.Message) - assert.NotNil(t, agentLog.Timestamp) - case <-time.After(time.Second): - t.Fatal("Timed out waiting for log message") - } - } - - assert.Equal(t, tt.expectedWrites, receivedWrites) - }) - } -} - -func TestStderrWrite(t *testing.T) { - tests := []struct { - name string - input string - expectedWrites int - }{ - { - name: "Single write within buffer size", - input: "Error: Something went wrong", - expectedWrites: 1, - }, - { - name: "Multiple writes within buffer size", - input: "This is a longer error message that will be split into multiple writes.", - expectedWrites: 1, - }, - { - name: "Large write exceeding buffer size", - input: string(make([]byte, bufSize*2)), - expectedWrites: 3, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - eventLogChan := make(chan interface{}, 10) - s := &Stderr{ - EventSender: func(event interface{}) error { - eventLogChan <- event - return nil - }, - ComputationId: "test-computation", - StateMachine: NewStateMachine(), - } - - err := s.StateMachine.Transition(pkgmanager.VmRunning) - assert.NoError(t, err) - - n, err := s.Write([]byte(tt.input)) - - assert.NoError(t, err) - assert.Equal(t, len(tt.input), n) - - var receivedWrites int - for i := 0; i < tt.expectedWrites; i++ { - select { - case msg := <-eventLogChan: - receivedWrites++ - switch logEv := msg.(type) { - case *Log: - assert.NotNil(t, logEv) - assert.Equal(t, "test-computation", logEv.ComputationId) - assert.Equal(t, slog.LevelError.String(), logEv.Level) - assert.NotEmpty(t, logEv.Message) - assert.NotNil(t, logEv.Timestamp) - case *Event: - assert.NotNil(t, logEv) - assert.Equal(t, "test-computation", logEv.ComputationId) - assert.Equal(t, pkgmanager.VmRunning.String(), logEv.EventType) - assert.Equal(t, pkgmanager.Warning.String(), logEv.Status) - assert.NotNil(t, logEv.Timestamp) - } - case <-time.After(time.Second): - t.Fatal("Timed out waiting for log message") - } - } - - assert.Equal(t, tt.expectedWrites, receivedWrites) - }) - } -} - -func TestStdoutWriteErrorHandling(t *testing.T) { - eventLogChan := make(chan interface{}, 10) - s := &Stdout{ - EventSender: func(event interface{}) error { - eventLogChan <- event - return assert.AnError - }, - ComputationId: "test-computation", - } - - message := []byte("This should fail") - n, err := s.Write(message) - - assert.Error(t, err) - assert.Equal(t, len(message), n) - assert.Equal(t, assert.AnError, err) -} - -func TestStderrWriteErrorHandling(t *testing.T) { - eventLogChan := make(chan interface{}, 10) - s := &Stderr{ - EventSender: func(event interface{}) error { - eventLogChan <- event - return assert.AnError - }, - ComputationId: "test-computation", - } - - message := []byte("This should fail") - n, err := s.Write(message) - - assert.Error(t, err) - assert.Equal(t, len(message), n) - assert.Equal(t, assert.AnError, err) -} diff --git a/manager/vm/mocks/provider.go b/manager/vm/mocks/provider.go index 29c9d5d0..60c2959c 100644 --- a/manager/vm/mocks/provider.go +++ b/manager/vm/mocks/provider.go @@ -23,17 +23,17 @@ func (_m *Provider) EXPECT() *Provider_Expecter { return &Provider_Expecter{mock: &_m.Mock} } -// Execute provides a mock function with given fields: config, eventSender, computationId -func (_m *Provider) Execute(config interface{}, eventSender vm.EventSender, computationId string) vm.VM { - ret := _m.Called(config, eventSender, computationId) +// Execute provides a mock function with given fields: config, computationId +func (_m *Provider) Execute(config interface{}, computationId string) vm.VM { + ret := _m.Called(config, computationId) if len(ret) == 0 { panic("no return value specified for Execute") } var r0 vm.VM - if rf, ok := ret.Get(0).(func(interface{}, vm.EventSender, string) vm.VM); ok { - r0 = rf(config, eventSender, computationId) + if rf, ok := ret.Get(0).(func(interface{}, string) vm.VM); ok { + r0 = rf(config, computationId) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(vm.VM) @@ -50,15 +50,14 @@ type Provider_Execute_Call struct { // Execute is a helper method to define mock.On call // - config interface{} -// - eventSender vm.EventSender // - computationId string -func (_e *Provider_Expecter) Execute(config interface{}, eventSender interface{}, computationId interface{}) *Provider_Execute_Call { - return &Provider_Execute_Call{Call: _e.mock.On("Execute", config, eventSender, computationId)} +func (_e *Provider_Expecter) Execute(config interface{}, computationId interface{}) *Provider_Execute_Call { + return &Provider_Execute_Call{Call: _e.mock.On("Execute", config, computationId)} } -func (_c *Provider_Execute_Call) Run(run func(config interface{}, eventSender vm.EventSender, computationId string)) *Provider_Execute_Call { +func (_c *Provider_Execute_Call) Run(run func(config interface{}, computationId string)) *Provider_Execute_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(interface{}), args[1].(vm.EventSender), args[2].(string)) + run(args[0].(interface{}), args[1].(string)) }) return _c } @@ -68,7 +67,7 @@ func (_c *Provider_Execute_Call) Return(_a0 vm.VM) *Provider_Execute_Call { return _c } -func (_c *Provider_Execute_Call) RunAndReturn(run func(interface{}, vm.EventSender, string) vm.VM) *Provider_Execute_Call { +func (_c *Provider_Execute_Call) RunAndReturn(run func(interface{}, string) vm.VM) *Provider_Execute_Call { _c.Call.Return(run) return _c } diff --git a/manager/vm/vm.go b/manager/vm/vm.go index c37d3c0d..98fd4d84 100644 --- a/manager/vm/vm.go +++ b/manager/vm/vm.go @@ -21,7 +21,7 @@ type VM interface { GetConfig() interface{} } -type Provider func(config interface{}, eventSender EventSender, computationId string) VM +type Provider func(config interface{}, computationId string) VM type Event struct { EventType string @@ -38,5 +38,3 @@ type Log struct { Level string Timestamp *timestamppb.Timestamp } - -type EventSender func(event interface{}) error diff --git a/pkg/clients/grpc/connect.go b/pkg/clients/grpc/connect.go index 18d0390f..f7959e9d 100644 --- a/pkg/clients/grpc/connect.go +++ b/pkg/clients/grpc/connect.go @@ -68,6 +68,10 @@ type AgentClientConfig struct { AttestedTLS bool `env:"ATTESTED_TLS" envDefault:"false"` } +type ManagerClientConfig struct { + BaseConfig +} + type CVMClientConfig struct { BaseConfig } diff --git a/pkg/clients/grpc/manager/manager.go b/pkg/clients/grpc/manager/manager.go index 370d8193..736796bc 100644 --- a/pkg/clients/grpc/manager/manager.go +++ b/pkg/clients/grpc/manager/manager.go @@ -8,7 +8,7 @@ import ( ) // NewManagerClient creates new manager gRPC client instance. -func NewManagerClient(cfg grpc.CVMClientConfig) (grpc.Client, manager.ManagerServiceClient, error) { +func NewManagerClient(cfg grpc.ManagerClientConfig) (grpc.Client, manager.ManagerServiceClient, error) { client, err := grpc.NewClient(cfg) if err != nil { return nil, nil, err diff --git a/pkg/clients/grpc/manager/manager_test.go b/pkg/clients/grpc/manager/manager_test.go index ff72574c..49ae5627 100644 --- a/pkg/clients/grpc/manager/manager_test.go +++ b/pkg/clients/grpc/manager/manager_test.go @@ -13,12 +13,12 @@ import ( func TestNewManagerClient(t *testing.T) { tests := []struct { name string - cfg grpc.CVMClientConfig + cfg grpc.ManagerClientConfig err error }{ { name: "Valid config", - cfg: grpc.CVMClientConfig{ + cfg: grpc.ManagerClientConfig{ BaseConfig: grpc.BaseConfig{ URL: "localhost:7001", },