NOISSUE - Add test server (#80)

* add test server

Signed-off-by: SammyOina <sammyoina@gmail.com>

* clean up and update docs

Signed-off-by: SammyOina <sammyoina@gmail.com>

* update docs

Signed-off-by: SammyOina <sammyoina@gmail.com>

* fix lint

Signed-off-by: SammyOina <sammyoina@gmail.com>

---------

Signed-off-by: SammyOina <sammyoina@gmail.com>
This commit is contained in:
Sammy Kerata Oina
2024-02-07 18:16:27 +03:00
committed by GitHub
parent 6d0100c096
commit e2fb7ea88d
12 changed files with 306 additions and 231 deletions
-58
View File
@@ -1,58 +0,0 @@
// Copyright (c) Ultraviolet
// SPDX-License-Identifier: Apache-2.0
package cli
import (
"encoding/json"
"log"
"github.com/spf13/cobra"
"github.com/ultravioletrs/cocos/agent"
"github.com/ultravioletrs/cocos/manager"
)
func (cli *CLI) NewRunCmd() *cobra.Command {
return &cobra.Command{
Use: "run",
Short: "Upload a computation manifest json",
Example: "run '<computation>'",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
computationStr := args[0]
var cmp agent.Computation
if err := json.Unmarshal([]byte(computationStr), &cmp); err != nil {
log.Fatalf("Error unmarshling computation json: %v", err)
}
req := manager.ComputationRunReq{
Id: cmp.ID,
Description: cmp.Description,
Name: cmp.Name,
ResultConsumers: cmp.ResultConsumers,
AgentConfig: &manager.AgentConfig{
Port: cmp.AgentConfig.Port,
Host: cmp.AgentConfig.Host,
CertFile: cmp.AgentConfig.CertFile,
KeyFile: cmp.AgentConfig.KeyFile,
LogLevel: cmp.AgentConfig.LogLevel,
},
}
for _, data := range cmp.Datasets {
req.Datasets = append(req.Datasets, &manager.Dataset{Id: data.ID, Provider: data.Provider})
}
for _, algo := range cmp.Algorithms {
req.Algorithms = append(req.Algorithms, &manager.Algorithm{Id: algo.ID, Provider: algo.Provider})
}
response, err := cli.managerSDK.Run(cmd.Context(), &req)
if err != nil {
log.Fatalf("Error running computation: %v", err)
}
log.Printf("Successfully run computation, agent address: %v", response)
},
}
}
+3 -6
View File
@@ -4,17 +4,14 @@ package cli
import (
"github.com/ultravioletrs/cocos/agent"
"github.com/ultravioletrs/cocos/manager"
)
type CLI struct {
agentSDK agent.Service
managerSDK manager.Service
agentSDK agent.Service
}
func New(agentSDK agent.Service, managerSDK manager.Service) *CLI {
func New(agentSDK agent.Service) *CLI {
return &CLI{
agentSDK: agentSDK,
managerSDK: managerSDK,
agentSDK: agentSDK,
}
}
+8 -89
View File
@@ -6,26 +6,21 @@ import (
"fmt"
"log"
"os"
"strings"
mglog "github.com/absmach/magistrala/logger"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/ultravioletrs/cocos/cli"
"github.com/ultravioletrs/cocos/internal/env"
managersvc "github.com/ultravioletrs/cocos/manager"
"github.com/ultravioletrs/cocos/manager/qemu"
"github.com/ultravioletrs/cocos/pkg/clients/grpc"
"github.com/ultravioletrs/cocos/pkg/clients/grpc/agent"
"github.com/ultravioletrs/cocos/pkg/sdk"
)
const (
svcName = "cli"
envPrefixAgentGRPC = "AGENT_GRPC_"
envPrefixManagerGRPC = "MANAGER_GRPC_"
completion = "completion"
envPrefixQemu = "MANAGER_QEMU_"
svcName = "cli"
envPrefixAgentGRPC = "AGENT_GRPC_"
completion = "completion"
)
type config struct {
@@ -56,22 +51,9 @@ func main() {
}
defer agentGRPCClient.Close()
qemuCfg := qemu.Config{}
if err := env.Parse(&qemuCfg, env.Options{Prefix: envPrefixQemu}); err != nil {
logger.Error(fmt.Sprintf("failed to load QEMU configuration: %s", err))
return
}
exe, args, err := qemu.ExecutableAndArgs(qemuCfg)
if err != nil {
logger.Error(fmt.Sprintf("failed to parse QEMU configuration: %s", err))
return
}
logger.Info(fmt.Sprintf("%s %s", exe, strings.Join(args, " ")))
agentSDK := sdk.NewAgentSDK(logger, agentClient)
managerSDK := managersvc.New(qemuCfg, logger, make(chan *managersvc.ClientStreamMessage))
cliSVC := cli.New(agentSDK, managerSDK)
cliSVC := cli.New(agentSDK)
rootCmd := &cobra.Command{
Use: "cocos-cli [command]",
@@ -101,80 +83,17 @@ func main() {
},
}
agentCmd := &cobra.Command{
Use: "agent [command]",
Short: "CLI application for agent Service API",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("CLI application for agent Service API\n\n")
fmt.Printf("Usage:\n %s [command]\n\n", cmd.CommandPath())
fmt.Printf("Available Commands:\n")
// Filter out "completion" command
availableCommands := make([]*cobra.Command, 0)
for _, subCmd := range cmd.Commands() {
if subCmd.Name() != completion {
availableCommands = append(availableCommands, subCmd)
}
}
for _, subCmd := range availableCommands {
fmt.Printf(" %-15s%s\n", subCmd.Name(), subCmd.Short)
}
fmt.Printf("\nFlags:\n")
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
fmt.Printf(" -%s, --%s %s\n", flag.Shorthand, flag.Name, flag.Usage)
})
fmt.Printf("\nUse \"%s [command] --help\" for more information about a command.\n", cmd.CommandPath())
},
}
managerCmd := &cobra.Command{
Use: "manager [command]",
Short: "CLI application for manager Service API",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("CLI application for manager Service API\n\n")
fmt.Printf("Usage:\n %s [command]\n\n", cmd.CommandPath())
fmt.Printf("Available Commands:\n")
// Filter out "completion" command
availableCommands := make([]*cobra.Command, 0)
for _, subCmd := range cmd.Commands() {
if subCmd.Name() != completion {
availableCommands = append(availableCommands, subCmd)
}
}
for _, subCmd := range availableCommands {
fmt.Printf(" %-15s%s\n", subCmd.Name(), subCmd.Short)
}
fmt.Printf("\nFlags:\n")
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
fmt.Printf(" -%s, --%s %s\n", flag.Shorthand, flag.Name, flag.Usage)
})
fmt.Printf("\nUse \"%s [command] --help\" for more information about a command.\n", cmd.CommandPath())
},
}
// Root Commands
rootCmd.AddCommand(agentCmd)
rootCmd.AddCommand(managerCmd)
// Agent Commands
agentCmd.AddCommand(cliSVC.NewAlgorithmsCmd())
agentCmd.AddCommand(cliSVC.NewDatasetsCmd())
agentCmd.AddCommand(cliSVC.NewResultsCmd())
rootCmd.AddCommand(cliSVC.NewAlgorithmsCmd())
rootCmd.AddCommand(cliSVC.NewDatasetsCmd())
rootCmd.AddCommand(cliSVC.NewResultsCmd())
attestaionCmd := cliSVC.NewAttestationCmd()
agentCmd.AddCommand(attestaionCmd)
rootCmd.AddCommand(attestaionCmd)
// Attestation commands
attestaionCmd.AddCommand(cliSVC.NewGetAttestationCmd())
attestaionCmd.AddCommand(cliSVC.NewValidateAttestationValidationCmd())
// Manager commands
managerCmd.AddCommand(cliSVC.NewRunCmd())
if err := rootCmd.Execute(); err != nil {
logger.Error(fmt.Sprintf("Command execution failed: %s", err))
return
+3 -5
View File
@@ -28,11 +28,9 @@ import (
)
const (
svcName = "manager"
envPrefixGRPC = "MANAGER_GRPC_"
envPrefixQemu = "MANAGER_QEMU_"
defSvcGRPCPort = "7001"
defSvcHTTPPort = "9021"
svcName = "manager"
envPrefixGRPC = "MANAGER_GRPC_"
envPrefixQemu = "MANAGER_QEMU_"
)
type config struct {
+3 -11
View File
@@ -135,7 +135,7 @@ NB: we set environment variables that we will use in the shell process where we
## Deployment
To start the service outside of the container, execute the following shell script:
To start the service, execute the following shell script (note a server needs to be running see [here](../test/manager-server/README.md)):
```bash
# download the latest version of the service
@@ -150,6 +150,7 @@ make manager
make install
# set the environment variables and run the service
MANAGER_GRPC_URL=localhost:7001
MANAGER_LOG_LEVEL=debug \
MANAGER_QEMU_USE_SUDO=false \
MANAGER_QEMU_ENABLE_SEV=false \
@@ -159,6 +160,7 @@ MANAGER_QEMU_ENABLE_SEV=false \
To enable [AMD SEV](https://www.amd.com/en/developer/sev.html) support, start manager like this
```sh
MANAGER_GRPC_URL=localhost:7001
MANAGER_LOG_LEVEL=debug \
MANAGER_QEMU_USE_SUDO=true \
MANAGER_QEMU_ENABLE_SEV=true \
@@ -166,16 +168,6 @@ MANAGER_QEMU_SEV_CBITPOS=51 \
./build/cocos-manager
```
### Create QEMU virtual machine (VM)
To create an instance of VM and run a computation, run
```sh
go run cmd/cli/main.go manager run '{"id":"123","name":"Sample Computation","description":"A sample computation","status":"Processing","owner":"John Doe","start_time":"2023-11-03T12:03:21.705171284+03:00","end_time":"2023-11-03T13:03:21.705171532+03:00","datasets":[{"provider":"Provider1","id":"Dataset1"},{"provider":"Provider2","id":"Dataset2"}],"algorithms":[{"provider":"AlgorithmProvider1","id":"Algorithm1"}],"result_consumers":["Consumer1","Consumer2"], "agent_config": {"port":"7002"}}'
```
You should be able to create multiple instances by reruning the command.
### Verifying VM launch
NB: To verify that the manager successfully launched the VM, you need to open two terminals on the same machine. In one terminal, you need to launch `go run main.go` (with the environment variables of choice) and in the other, you can run the verification commands.
+23 -28
View File
@@ -3,49 +3,44 @@
package grpc
import (
"context"
"github.com/ultravioletrs/cocos/manager"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc/peer"
)
type grpcServer struct {
manager.UnimplementedManagerServiceServer
incoming chan *manager.ClientStreamMessage
responses chan *manager.ComputationRunReq
ctx context.Context
incoming chan *manager.ClientStreamMessage
svc Service
}
type Service interface {
Run(ipAddress string) manager.ComputationRunReq
}
// NewServer returns new AuthServiceServer instance.
func NewServer(ctx context.Context, incoming chan *manager.ClientStreamMessage, responses chan *manager.ComputationRunReq) manager.ManagerServiceServer {
func NewServer(incoming chan *manager.ClientStreamMessage, svc Service) manager.ManagerServiceServer {
return &grpcServer{
incoming: incoming,
responses: responses,
incoming: incoming,
svc: svc,
}
}
func (s *grpcServer) Process(stream manager.ManagerService_ProcessServer) error {
eg, _ := errgroup.WithContext(s.ctx)
eg.Go(func() error {
for {
req, err := stream.Recv()
if err != nil {
return err
}
s.incoming <- req
for {
req, err := stream.Recv()
if err != nil {
return err
}
})
eg.Go(func() error {
for resp := range s.responses {
if err := stream.Send(resp); err != nil {
return err
if _, ok := req.Message.(*manager.ClientStreamMessage_Whoami); ok {
client, ok := peer.FromContext(stream.Context())
if ok {
req := s.svc.Run(client.Addr.String())
if err := stream.Send(&req); err != nil {
return err
}
}
}
return nil
})
return eg.Wait()
s.incoming <- req
}
}
+9 -19
View File
@@ -585,7 +585,6 @@ type AgentConfig struct {
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"`
InstanceId string `protobuf:"bytes,8,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`
}
func (x *AgentConfig) Reset() {
@@ -669,13 +668,6 @@ func (x *AgentConfig) GetLogLevel() string {
return ""
}
func (x *AgentConfig) GetInstanceId() string {
if x != nil {
return x.InstanceId
}
return ""
}
var File_manager_manager_proto protoreflect.FileDescriptor
var file_manager_manager_proto_rawDesc = []byte{
@@ -748,7 +740,7 @@ var file_manager_manager_proto_rawDesc = []byte{
0x69, 0x74, 0x68, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
0x22, 0xf7, 0x01, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x22, 0xd6, 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,
@@ -761,16 +753,14 @@ var file_manager_manager_proto_rawDesc = []byte{
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, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x32, 0x5b, 0x0a, 0x0e, 0x4d, 0x61,
0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x49, 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, 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, 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,
0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x32, 0x5b, 0x0a, 0x0e, 0x4d, 0x61, 0x6e,
0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x49, 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, 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,
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,
}
var (
-1
View File
@@ -72,5 +72,4 @@ message AgentConfig {
string client_ca_file = 5;
string server_ca_file = 6;
string log_level = 7;
string instance_id = 8;
}
+19
View File
@@ -0,0 +1,19 @@
# Manager test server
Manager service is a grpc client. It connects to a server and sends a whoAmIRequest.
The server then responds with a run computation request. Once manager service receives the computation request it will launch an agent service in a virtual machine and pass the computation manifest. Agent will then pass logs and events to manager which are forwarded to the server. `main.go` is a sample of how such a server would be implemented. This is a very simple example for testing purposes.
## Configuration
The service is configured using the environment variables from the following table. Note that any unset variables will be replaced with their default values.
| Variable | Description | Default |
| ---------------- | ---------------------------------------- | ------- |
| HOST | Manager service gRPC host | |
| PORT | Manager service gRPC port | 7001 |
| SERVER_CERT | Path to server certificate in pem format | |
| SERVER_KEY | Path to server key in pem format | |
## Running
```shell
go run main.go
```
+97
View File
@@ -0,0 +1,97 @@
// Copyright (c) Ultraviolet
// SPDX-License-Identifier: Apache-2.0
package main
import (
"context"
"fmt"
"log"
"log/slog"
"os"
mglog "github.com/absmach/magistrala/logger"
"github.com/ultravioletrs/cocos/internal/env"
"github.com/ultravioletrs/cocos/internal/server"
grpcserver "github.com/ultravioletrs/cocos/internal/server/grpc"
"github.com/ultravioletrs/cocos/manager"
managergrpc "github.com/ultravioletrs/cocos/manager/api/grpc"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
const (
svcName = "manager_test_server"
defaultPort = "7001"
)
type svc struct {
logger *slog.Logger
}
func (s *svc) Run(ipAdress string) manager.ComputationRunReq {
s.logger.Debug(fmt.Sprintf("received who am on ip address %s", ipAdress))
return manager.ComputationRunReq{
Id: "1",
Name: "sample computation",
Description: "sample descrption",
Datasets: []*manager.Dataset{{Id: "1", Provider: "provider1"}},
Algorithms: []*manager.Algorithm{{Id: "1", Provider: "provider1"}},
ResultConsumers: []string{"consumer1"},
AgentConfig: &manager.AgentConfig{
Port: "7002",
LogLevel: "debug",
},
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
g, ctx := errgroup.WithContext(ctx)
incomingChan := make(chan *manager.ClientStreamMessage)
logger, err := mglog.New(os.Stdout, "debug")
if err != nil {
log.Fatalf(err.Error())
}
go func() {
for incoming := range incomingChan {
switch incoming.Message.(type) {
case *manager.ClientStreamMessage_Whoami:
fmt.Println("received whoamI")
case *manager.ClientStreamMessage_RunRes:
fmt.Println("received runRes")
case *manager.ClientStreamMessage_AgentEvent:
fmt.Println("received agent event")
case *manager.ClientStreamMessage_AgentLog:
fmt.Println("received agent log")
}
fmt.Println(incoming.Message)
}
}()
registerAgentServiceServer := func(srv *grpc.Server) {
reflection.Register(srv)
manager.RegisterManagerServiceServer(srv, managergrpc.NewServer(incomingChan, &svc{logger: logger}))
}
grpcServerConfig := server.Config{Port: defaultPort}
if err := env.Parse(&grpcServerConfig, env.Options{}); err != nil {
logger.Error(fmt.Sprintf("failed to load %s gRPC client configuration : %s", svcName, err))
return
}
gs := grpcserver.New(ctx, cancel, svcName, grpcServerConfig, registerAgentServiceServer, logger)
g.Go(func() error {
return gs.Start()
})
g.Go(func() error {
return server.StopHandler(ctx, cancel, logger, svcName, gs)
})
if err := g.Wait(); err != nil {
logger.Error(fmt.Sprintf("%s service terminated: %s", svcName, err))
}
}
+7 -14
View File
@@ -16,11 +16,7 @@ pip3 install pandas scikit-learn
### Agent-CLI interaction
In the VM, open a console and start `agent`:
```sh
AGENT_LOG_LEVEL=info AGENT_GRPC_URL=10.0.2.15:7002 go run cmd/agent/main.go
```
Agent is started automatically in the VM when launched but requires configuration and manifest to be passed by manager. Alternatively you can pass configuration using this [simplified script](./agent-config/main.go)
Open console on the host, and run
@@ -28,26 +24,23 @@ Open console on the host, and run
export AGENT_GRPC_URL=localhost:7002
export MANAGER_GRPC_URL=localhost:7001
# Run CLI to provide manifest
go run cmd/cli/main.go run '{"id":"123","name":"Sample Computation","description":"A sample computation","status":"Processing","owner":"John Doe","start_time":"2023-11-03T12:03:21.705171284+03:00","end_time":"2023-11-03T13:03:21.705171532+03:00","datasets":[{"provider":"Provider1","id":"Dataset1"},{"provider":"Provider2","id":"Dataset2"}],"algorithms":[{"provider":"AlgorithmProvider1","id":"Algorithm1"}],"result_consumers":["Consumer1","Consumer2"],"ttl":3600,"metadata":{"key1":"value1","key2":42}, "timeout": "2m"}'
# Retieve Attestation
go run cmd/cli/main.go agent attestation get '<report_data>'
go run cmd/cli/main.go attestation get '<report_data>'
# Validate Attestation
go run cmd/cli/main.go agent attestation validate '<attesation>' '<report_data>'
go run cmd/cli/main.go attestation validate '<attesation>' '<report_data>'
# Run the CLI program with algorithm input
go run cmd/cli/main.go agent algo test/manual/algo/lin_reg.py Algorithm1 AlgorithmProvider1
go run cmd/cli/main.go algo test/manual/algo/lin_reg.py Algorithm1 AlgorithmProvider1
# 2023/09/21 10:43:53 Uploading algorithm binary: test/manual/algo/lin_reg.py
# Run the CLI program with dataset input
go run cmd/cli/main.go agent data test/manual/data/iris.csv Dataset1 Provider1
go run cmd/cli/main.go agent data test/manual/data/iris.csv Dataset2 Provider2
go run cmd/cli/main.go data test/manual/data/iris.csv Dataset1 Provider1
go run cmd/cli/main.go data test/manual/data/iris.csv Dataset2 Provider2
# 2023/09/21 10:45:25 Uploading dataset CSV: test/manual/data/iris.csv
# Run the CLI program to fetch computation result
go run cmd/cli/main.go agent result Consumer1
go run cmd/cli/main.go result Consumer1
# 2023/09/21 10:45:39 Retrieving computation result file
# 2023/09/21 10:45:40 Computation result retrieved and saved successfully!
```
+134
View File
@@ -0,0 +1,134 @@
// Copyright (c) Ultraviolet
// SPDX-License-Identifier: Apache-2.0
// Simplified script to pass configs to agent without manager and read logs and events for manager.
// This tool is meant for testing purposes.
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/mdlayher/vsock"
)
const VsockConfigPort uint32 = 9999
type AgentConfig struct {
LogLevel string `json:"log_level"`
InstanceID string `json:"instance_id"`
Host string `json:"host"`
Port string `json:"port"`
CertFile string `json:"cert_file"`
KeyFile string `json:"server_key"`
}
type Computation struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Datasets Datasets `json:"datasets,omitempty"`
Algorithms Algorithms `json:"algorithms,omitempty"`
ResultConsumers []string `json:"result_consumers,omitempty"`
AgentConfig AgentConfig `json:"agent_config,omitempty"`
}
func (d *Datasets) String() string {
dat, err := json.Marshal(d)
if err != nil {
return ""
}
return string(dat)
}
func (a *Algorithms) String() string {
dat, err := json.Marshal(a)
if err != nil {
return ""
}
return string(dat)
}
type Dataset struct {
Dataset []byte `json:"-"`
Provider string `json:"provider,omitempty"`
ID string `json:"id,omitempty"`
}
type Datasets []Dataset
type Algorithm struct {
Algorithm []byte `json:"-"`
Provider string `json:"provider,omitempty"`
ID string `json:"id,omitempty"`
}
type Algorithms []Algorithm
func main() {
l, err := vsock.Listen(9997, nil)
if err != nil {
log.Fatal(err)
}
l2, err := vsock.Listen(9998, nil)
if err != nil {
log.Fatal(err)
}
ac := Computation{
ID: "123",
Datasets: Datasets{Dataset{ID: "1", Provider: "pr1"}},
Algorithms: Algorithms{Algorithm{ID: "1", Provider: "pr1"}},
ResultConsumers: []string{"1"},
AgentConfig: AgentConfig{
LogLevel: "debug",
Port: "7002",
},
}
fmt.Println(SendAgentConfig(3, ac))
go func() {
for {
conn, err := l.Accept()
if err != nil {
continue
}
b := make([]byte, 1024)
n, err := conn.Read(b)
if err != nil {
continue
}
conn.Close()
fmt.Println(string(b[:n]))
}
}()
for {
conn, err := l2.Accept()
if err != nil {
continue
}
b := make([]byte, 1024)
n, err := conn.Read(b)
if err != nil {
continue
}
conn.Close()
fmt.Println(string(b[:n]))
}
}
func SendAgentConfig(cid uint32, ac Computation) error {
conn, err := vsock.Dial(cid, VsockConfigPort, nil)
if err != nil {
return err
}
defer conn.Close()
payload, err := json.Marshal(ac)
if err != nil {
return err
}
if _, err := conn.Write(payload); err != nil {
return err
}
return nil
}