mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-08-07 15:26:26 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 064ab9dbb9 | |||
| 2b760ec207 | |||
| 2e612a2867 | |||
| f2f57ac413 | |||
| d50a6fcfda | |||
| d323fd3b7e | |||
| 35c2a9e92a | |||
| 5c406743e0 | |||
| b6f116474d | |||
| 3e3e02f132 | |||
| 4b38ac09dd |
@@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
- name: Set up protoc
|
||||
run: |
|
||||
PROTOC_VERSION=25.1
|
||||
PROTOC_VERSION=25.3
|
||||
PROTOC_GEN_VERSION=v1.31.0
|
||||
PROTOC_GRPC_VERSION=v1.3.0
|
||||
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
- name: Set up Cocos-AI
|
||||
run: |
|
||||
# Rename .pb.go files to .pb.go.tmp to prevent conflicts
|
||||
for p in $(ls manager/*.pb.go); do
|
||||
for p in $(ls pkg/manager/*.pb.go); do
|
||||
mv $p $p.tmp
|
||||
done
|
||||
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
make protoc
|
||||
|
||||
# Compare generated Go files with the original ones
|
||||
for p in $(ls manager/*.pb.go); do
|
||||
for p in $(ls pkg/manager/*.pb.go); do
|
||||
if ! cmp -s $p $p.tmp; then
|
||||
echo "Proto file and generated Go file $p are out of sync!"
|
||||
exit 1
|
||||
|
||||
@@ -5,8 +5,6 @@ GOARCH ?= amd64
|
||||
VERSION ?= $(shell git describe --abbrev=0 --tags --always)
|
||||
COMMIT ?= $(shell git rev-parse HEAD)
|
||||
TIME ?= $(shell date +%F_%T)
|
||||
CLI_SOURCE = ./cmd/cli/main.go
|
||||
CLI_BIN = ${BUILD_DIR}/cocos-cli
|
||||
empty:=
|
||||
space:= $(empty) $(empty)
|
||||
|
||||
@@ -26,10 +24,6 @@ all: $(SERVICES)
|
||||
$(SERVICES):
|
||||
$(call compile_service,$(@))
|
||||
|
||||
|
||||
install-cli: cli
|
||||
cp ${CLI_BIN} ~/.local/bin/cocos-cli
|
||||
|
||||
protoc:
|
||||
protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative agent/agent.proto
|
||||
protoc -I. --go_out=./pkg --go_opt=paths=source_relative --go-grpc_out=./pkg --go-grpc_opt=paths=source_relative manager/manager.proto
|
||||
|
||||
@@ -12,6 +12,18 @@ Data is always encrypted, protected by hardware secure enclaves (Trusted Executi
|
||||
attested via secure remote attestation protocols, and invisible to cloud processors or any other
|
||||
3rd party to which computation is offloaded.
|
||||
|
||||
## Features
|
||||
|
||||
Cocos AI is implementing the following features:
|
||||
|
||||
- TEE enablement, deployment and monitoring (secure VM manager)
|
||||
- HAL for TEEs based on hardened Linux kernel, secure bootloader and custom-tailored embedded rootfs for minimal TCB
|
||||
- In-enclave agent, netowrking controller and other system software
|
||||
- Encrypted asynchronous data transfer and result delivery
|
||||
- API for programmable platform manipulation
|
||||
- HW and SW supported attestation with verification tools
|
||||
- CLI for system interaction
|
||||
|
||||
## Usage
|
||||
|
||||
The quickest way to start using Cocos is via the CLI. The latest version can be downloaded from the [official releases page][rel].
|
||||
@@ -23,17 +35,18 @@ make cli
|
||||
./build/cocos-cli version
|
||||
```
|
||||
|
||||
Additional details on using the CLI can be found in the [CLI documentation](https://docs.cocos.ai/cli).
|
||||
Additional details on using the CLI can be found in the [CLI documentation][cli].
|
||||
|
||||
## Documentation
|
||||
|
||||
Official documentation is hosted at [Cocos official docs page][docs]. Documentation is auto-generated, checkout the instructions on [official docs repository](https://github.com/ultravioletrs/docs).
|
||||
|
||||
## License
|
||||
Cocos AI is a proprietary product created by Ultraviolet company.
|
||||
Cocos AI is published under permissive open-source [Apache-2.0](LICENSE) license.
|
||||
|
||||
[cc]: https://confidentialcomputing.io/white-papers-reports/
|
||||
[cocos]: https://cocos.ai/
|
||||
[rel]: https://github.com/ultraviolet/cocos/releases
|
||||
[rel]: https://github.com/ultravioletrs/cocos/releases
|
||||
[tee]: https://en.wikipedia.org/wiki/Trusted_execution_environment
|
||||
|
||||
[docs]: https://docs.cocos.ultraviolet.rs
|
||||
[cli]: https://docs.cocos.ultraviolet.rs/cli
|
||||
|
||||
+5
-5
@@ -23,15 +23,15 @@ The service is configured using the environment variables from the following tab
|
||||
To start the service outside of the container, execute the following shell script:
|
||||
|
||||
```bash
|
||||
# download the latest version of the service
|
||||
go get github.com/ultravioletrs/cocos
|
||||
# Download the latest version of the service
|
||||
git clone git@github.com:ultravioletrs/cocos.git
|
||||
|
||||
cd $GOPATH/src/github.com/ultravioletrs/cocos
|
||||
cd cocos
|
||||
|
||||
# compile the agent
|
||||
# Compile the service
|
||||
make agent
|
||||
|
||||
# set the environment variables and run the service
|
||||
# Run the service
|
||||
./build/cocos-agent
|
||||
```
|
||||
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v4.25.1
|
||||
// protoc v4.25.3
|
||||
// source: agent/agent.proto
|
||||
|
||||
package agent
|
||||
@@ -324,7 +324,7 @@ type AttestationRequest struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ReportData []byte `protobuf:"bytes,1,opt,name=report_data,json=reportData,proto3" json:"report_data,omitempty"`
|
||||
ReportData []byte `protobuf:"bytes,1,opt,name=report_data,json=reportData,proto3" json:"report_data,omitempty"` // Should be of length 64.
|
||||
}
|
||||
|
||||
func (x *AttestationRequest) Reset() {
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ message ResultResponse {
|
||||
}
|
||||
|
||||
message AttestationRequest {
|
||||
bytes report_data = 1;
|
||||
bytes report_data = 1; // Should be of length 64.
|
||||
}
|
||||
|
||||
message AttestationResponse {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v4.25.1
|
||||
// - protoc v4.25.3
|
||||
// source: agent/agent.proto
|
||||
|
||||
package agent
|
||||
|
||||
@@ -147,7 +147,7 @@ func encodeAttestationRequest(_ context.Context, request interface{}) (interface
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid request type: %T", request)
|
||||
}
|
||||
return &agent.AttestationRequest{ReportData: req.ReportData}, nil
|
||||
return &agent.AttestationRequest{ReportData: req.ReportData[:]}, nil
|
||||
}
|
||||
|
||||
// decodeAttestationResponse is a transport/grpc.DecodeResponseFunc that
|
||||
@@ -208,7 +208,7 @@ func (c grpcClient) Attestation(ctx context.Context, request *agent.AttestationR
|
||||
ctx, cancel := context.WithTimeout(ctx, c.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := c.attestation(ctx, &attestationReq{ReportData: request.ReportData})
|
||||
res, err := c.attestation(ctx, &attestationReq{ReportData: [agent.ReportDataSize]byte(request.ReportData)})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -54,12 +54,9 @@ func (req resultReq) validate() error {
|
||||
}
|
||||
|
||||
type attestationReq struct {
|
||||
ReportData []byte
|
||||
ReportData [64]byte
|
||||
}
|
||||
|
||||
func (req attestationReq) validate() error {
|
||||
if req.ReportData == nil {
|
||||
return errors.New("malformed entity")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/go-kit/kit/transport/grpc"
|
||||
"github.com/ultravioletrs/cocos/agent"
|
||||
@@ -85,7 +86,10 @@ func encodeResultResponse(_ context.Context, response interface{}) (interface{},
|
||||
|
||||
func decodeAttestationRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*agent.AttestationRequest)
|
||||
return attestationReq{ReportData: req.ReportData}, nil
|
||||
if len(req.ReportData) != agent.ReportDataSize {
|
||||
return nil, errors.New("malformed report data, expect 64 bytes")
|
||||
}
|
||||
return attestationReq{ReportData: [agent.ReportDataSize]byte(req.ReportData)}, nil
|
||||
}
|
||||
|
||||
func encodeAttestationResponse(_ context.Context, response interface{}) (interface{}, error) {
|
||||
|
||||
@@ -66,7 +66,7 @@ func (lm *loggingMiddleware) Result(ctx context.Context, consumer string) (respo
|
||||
return lm.svc.Result(ctx, consumer)
|
||||
}
|
||||
|
||||
func (lm *loggingMiddleware) Attestation(ctx context.Context, reportData []byte) (response []byte, err error) {
|
||||
func (lm *loggingMiddleware) Attestation(ctx context.Context, reportData [agent.ReportDataSize]byte) (response []byte, err error) {
|
||||
defer func(begin time.Time) {
|
||||
message := fmt.Sprintf("Method Attestation took %s to complete", time.Since(begin))
|
||||
if err != nil {
|
||||
|
||||
@@ -59,7 +59,7 @@ func (ms *metricsMiddleware) Result(ctx context.Context, consumer string) ([]byt
|
||||
return ms.svc.Result(ctx, consumer)
|
||||
}
|
||||
|
||||
func (ms *metricsMiddleware) Attestation(ctx context.Context, reportData []byte) ([]byte, error) {
|
||||
func (ms *metricsMiddleware) Attestation(ctx context.Context, reportData [agent.ReportDataSize]byte) ([]byte, error) {
|
||||
defer func(begin time.Time) {
|
||||
ms.counter.With("method", "attestation").Add(1)
|
||||
ms.latency.With("method", "attestation").Observe(time.Since(begin).Seconds())
|
||||
|
||||
+6
-4
@@ -5,7 +5,6 @@ package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha512"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -21,6 +20,9 @@ import (
|
||||
|
||||
var _ Service = (*agentService)(nil)
|
||||
|
||||
// ReportDataSize is the size of the report data expected by the attestation service.
|
||||
const ReportDataSize = 64
|
||||
|
||||
var (
|
||||
// ErrMalformedEntity indicates malformed entity specification (e.g.
|
||||
// invalid username or password).
|
||||
@@ -52,7 +54,7 @@ type Service interface {
|
||||
Algo(ctx context.Context, algorithm Algorithm) error
|
||||
Data(ctx context.Context, dataset Dataset) error
|
||||
Result(ctx context.Context, consumer string) ([]byte, error)
|
||||
Attestation(ctx context.Context, reportData []byte) ([]byte, error)
|
||||
Attestation(ctx context.Context, reportData [ReportDataSize]byte) ([]byte, error)
|
||||
}
|
||||
|
||||
type agentService struct {
|
||||
@@ -181,12 +183,12 @@ func (as *agentService) Result(ctx context.Context, consumer string) ([]byte, er
|
||||
return as.result, as.runError
|
||||
}
|
||||
|
||||
func (as *agentService) Attestation(ctx context.Context, reportData []byte) ([]byte, error) {
|
||||
func (as *agentService) Attestation(ctx context.Context, reportData [ReportDataSize]byte) ([]byte, error) {
|
||||
provider, err := client.GetQuoteProvider()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
rawQuote, err := provider.GetRawQuote(sha512.Sum512(reportData))
|
||||
rawQuote, err := provider.GetRawQuote(reportData)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ type StateMachine struct {
|
||||
Transitions map[state]map[event]state
|
||||
StateFunctions map[state]func()
|
||||
logger *slog.Logger
|
||||
wg *sync.WaitGroup
|
||||
}
|
||||
|
||||
// NewStateMachine creates a new StateMachine.
|
||||
@@ -51,6 +52,7 @@ func NewStateMachine(logger *slog.Logger) *StateMachine {
|
||||
Transitions: make(map[state]map[event]state),
|
||||
StateFunctions: make(map[state]func()),
|
||||
logger: logger,
|
||||
wg: &sync.WaitGroup{},
|
||||
}
|
||||
|
||||
sm.Transitions[idle] = make(map[event]state)
|
||||
@@ -76,6 +78,8 @@ func NewStateMachine(logger *slog.Logger) *StateMachine {
|
||||
|
||||
// Start the state machine.
|
||||
func (sm *StateMachine) Start(ctx context.Context) {
|
||||
sm.wg.Add(1)
|
||||
defer sm.wg.Done()
|
||||
for {
|
||||
select {
|
||||
case event := <-sm.EventChan:
|
||||
|
||||
+1
-3
@@ -27,12 +27,11 @@ func TestStateMachineTransitions(t *testing.T) {
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Transition from %v to %v", testCase.fromState, testCase.expected), func(t *testing.T) {
|
||||
sm := NewStateMachine(mglog.NewMock())
|
||||
done := make(chan struct{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
sm.Start(ctx)
|
||||
close(done)
|
||||
}()
|
||||
sm.wg.Wait()
|
||||
sm.SetState(testCase.fromState)
|
||||
|
||||
sm.SendEvent(testCase.event)
|
||||
@@ -42,7 +41,6 @@ func TestStateMachineTransitions(t *testing.T) {
|
||||
}
|
||||
close(sm.EventChan)
|
||||
cancel()
|
||||
<-done
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+35
-14
@@ -21,16 +21,49 @@ To run a computation, use the following command:
|
||||
```
|
||||
|
||||
#### Get attestation
|
||||
Retrieves attestation information from the SEV guest and saves it to a file.
|
||||
To retrieve attestation from agent, use the following command:
|
||||
```bash
|
||||
./build/cocos-cli agent attestation get '<report_data>'
|
||||
```
|
||||
|
||||
#### Validate attestation
|
||||
Validates the retrieved attestation information against a specified policy and checks its authenticity.
|
||||
To validate and verify attestation from agent, use the following command:
|
||||
```bash
|
||||
./build/cocos-cli agent attestation validate '<attestation>' '<report_data>'
|
||||
./build/cocos-cli agent attestation validate '<attestation>' --report_data '<report_data>'
|
||||
```
|
||||
##### Flags
|
||||
- --config: Path to a JSON file containing the validation configuration. This can be used to override individual flags.
|
||||
- --report_data: Hex-encoded string representing the attestation report data. (Required for the validate command)
|
||||
- --host_data: Hex-encoded string representing the expected HOST_DATA field.
|
||||
- --family_id: Hex-encoded string representing the expected FAMILY_ID field.
|
||||
- --image_id: Hex-encoded string representing the expected IMAGE_ID field.
|
||||
- --report_id: Hex-encoded string representing the expected REPORT_ID field.
|
||||
- --report_id_ma: Hex-encoded string representing the expected REPORT_ID_MA field.
|
||||
- --measurement: Hex-encoded string representing the expected MEASUREMENT field.
|
||||
- --chip_id: Hex-encoded string representing the expected CHIP_ID field.
|
||||
- --minimum_tcb: Minimum acceptable value for CURRENT_TCB, COMMITTED_TCB, and REPORTED_TCB.
|
||||
- --minimum_launch_tcb: Minimum acceptable value for LAUNCH_TCB.
|
||||
- --minimum_guest_svn: Minimum acceptable SnpPolicy.
|
||||
- --minimum_build: Minimum 8-bit build number for AMD-SP firmware.
|
||||
- --check_crl: Download and check the CRL for revoked certificates (default: false).
|
||||
- --disallow_network: If true, disallows network downloads for verification (default: false).
|
||||
- --timeout: Duration to continue retrying failed HTTP requests (default: 2 minutes).
|
||||
- --max_retry_delay: Maximum duration to wait between HTTP request retries (default: 30 seconds).
|
||||
- --require_author_key: Require that AUTHOR_KEY_EN is set to 1 (default: false).
|
||||
- --require_id_block: Require that the VM was launched with an ID_BLOCK signed by a trusted key (default: false).
|
||||
- --permit_provisional_software: Allow provisional firmware (default: false).
|
||||
- --platform_info: Maximum acceptable PLATFORM_INFO field bit-wise (optional).
|
||||
- --minimum_version: Minimum AMD-SP firmware API version (major.minor) (optional).
|
||||
- --trusted_author_keys: Paths to x.509 certificates of trusted author keys (optional).
|
||||
- --trusted_author_key_hashes: Hex-encoded SHA-384 hashes of trusted author keys (optional).
|
||||
- --trusted_id_keys: Paths to x.509 certificates of trusted identity keys (optional).
|
||||
- --trusted_id_key_hashes: Hex-encoded SHA-384 hashes of trusted identity keys (optional).
|
||||
- --product: AMD product name for the chip that generated the attestation report (optional).
|
||||
- --stepping: Machine stepping for the chip that generated the attestation report (optional).
|
||||
- --CA_bundles_paths: Paths to CA bundles for the AMD product (optional).
|
||||
- --CA_bundles: PEM format CA bundles for the AMD product (optional).
|
||||
|
||||
#### Upload Algorithm
|
||||
|
||||
@@ -54,16 +87,4 @@ To retrieve the computation result, use the following command:
|
||||
|
||||
```bash
|
||||
./build/cocos-cli agent result
|
||||
```
|
||||
|
||||
## Installtion
|
||||
|
||||
To use the CLI, you have the option to install it globally on your system. Here's how:
|
||||
|
||||
### Build the CLI:
|
||||
|
||||
Navigate to the project root and run the following command to build the CLI binary:
|
||||
|
||||
```bash
|
||||
make install-cli
|
||||
```
|
||||
```
|
||||
+544
-12
@@ -3,18 +3,116 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-sev-guest/abi"
|
||||
"github.com/google/go-sev-guest/proto/check"
|
||||
"github.com/google/go-sev-guest/validate"
|
||||
"github.com/google/go-sev-guest/verify"
|
||||
"github.com/google/go-sev-guest/verify/trust"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/ultravioletrs/cocos/agent"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
const attestationFilePath = "attestation.txt"
|
||||
const (
|
||||
defaultMinimumTcb = 0
|
||||
defaultMinimumLaunchTcb = 0
|
||||
defaultMinimumGuestSvn = 0
|
||||
defaultGuestPolicy = 0x0000000000030000
|
||||
defaultMinimumBuild = 0
|
||||
defaultCheckCrl = false
|
||||
defaultTimeout = 2 * time.Minute
|
||||
defaultMaxRetryDelay = 30 * time.Second
|
||||
defaultRequireAuthor = false
|
||||
defaultRequireIdBlock = false
|
||||
defaultMinVersion = "0.0"
|
||||
size16 = 16
|
||||
size32 = 32
|
||||
size48 = 48
|
||||
size64 = 64
|
||||
attestationFilePath = "attestation.bin"
|
||||
exampleJSONConfig = `
|
||||
{
|
||||
"rootOfTrust":{
|
||||
"product":"test_product",
|
||||
"cabundlePaths":[
|
||||
"test_cabundlePaths"
|
||||
],
|
||||
"cabundles":[
|
||||
"test_Cabundles"
|
||||
],
|
||||
"checkCrl":true,
|
||||
"disallowNetwork":true
|
||||
},
|
||||
"policy":{
|
||||
"minimumGuestSvn":1,
|
||||
"policy":"1",
|
||||
"familyId":"AQIDBAUGBwgJCgsMDQ4PEA==",
|
||||
"imageId":"AQIDBAUGBwgJCgsMDQ4PEA==",
|
||||
"vmpl":0,
|
||||
"minimumTcb":"1",
|
||||
"minimumLaunchTcb":"1",
|
||||
"platformInfo":"1",
|
||||
"requireAuthorKey":true,
|
||||
"reportData":"J+60aXs8btm8VcGgaJYURGeNCu0FIyWMFXQ7ZUlJDC0FJGJizJsOzDIXgQ75UtPC+Zqe0A3dvnnf5VEeQ61RTg==",
|
||||
"measurement":"8s78ewoX7Xkfy1qsgVnkZwLDotD768Nqt6qTL5wtQOxHsLczipKM6bhDmWiHLdP4",
|
||||
"hostData":"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw=",
|
||||
"reportId":"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw=",
|
||||
"reportIdMa":"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw=",
|
||||
"chipId":"J+60aXs8btm8VcGgaJYURGeNCu0FIyWMFXQ7ZUlJDC0FJGJizJsOzDIXgQ75UtPC+Zqe0A3dvnnf5VEeQ61RTg==",
|
||||
"minimumBuild":1,
|
||||
"minimumVersion":"0.90",
|
||||
"permitProvisionalFirmware":true,
|
||||
"requireIdBlock":true,
|
||||
"trustedAuthorKeys":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"trustedAuthorKeyHashes":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"trustedIdKeys":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"trustedIdKeyHashes":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"product":{
|
||||
"name":"SEV_PRODUCT_MILAN",
|
||||
"stepping":1,
|
||||
"machineStepping":1
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
var (
|
||||
cfg = check.Config{Policy: &check.Policy{}, RootOfTrust: &check.RootOfTrust{}}
|
||||
cfgString string
|
||||
timeout time.Duration
|
||||
maxRetryDelay time.Duration
|
||||
platformInfo string
|
||||
stepping string
|
||||
trustedAuthorKeys []string
|
||||
trustedAuthorHashes []string
|
||||
trustedIdKeys []string
|
||||
trustedIdKeyHashes []string
|
||||
attestationFile string
|
||||
attestation []byte
|
||||
empty16 = [size16]byte{}
|
||||
empty32 = [size32]byte{}
|
||||
empty64 = [size64]byte{}
|
||||
defaultReportIdMa = []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}
|
||||
)
|
||||
|
||||
func (cli *CLI) NewAttestationCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
@@ -49,13 +147,21 @@ func (cli *CLI) NewAttestationCmd() *cobra.Command {
|
||||
func (cli *CLI) NewGetAttestationCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Retrieve attestation information from agent",
|
||||
Short: "Retrieve attestation information from agent. Report data expected in hex enoded string of length 64 bytes.",
|
||||
Example: "report <report_data>",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Println("Getting attestation")
|
||||
|
||||
result, err := cli.agentSDK.Attestation(cmd.Context(), []byte(args[0]))
|
||||
reportData, err := hex.DecodeString(args[0])
|
||||
if err != nil {
|
||||
log.Fatalf("attestation validation and verification failed with error: %s", err)
|
||||
}
|
||||
if len(reportData) != agent.ReportDataSize {
|
||||
log.Fatalf("report data must be a hex encoded string of length %d bytes", agent.ReportDataSize)
|
||||
}
|
||||
|
||||
result, err := cli.agentSDK.Attestation(cmd.Context(), [agent.ReportDataSize]byte(reportData))
|
||||
if err != nil {
|
||||
log.Fatalf("Error retrieving attestation: %v", err)
|
||||
}
|
||||
@@ -70,32 +176,458 @@ func (cli *CLI) NewGetAttestationCmd() *cobra.Command {
|
||||
}
|
||||
|
||||
func (cli *CLI) NewValidateAttestationValidationCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
cmd := &cobra.Command{
|
||||
Use: "validate",
|
||||
Short: "Validate and verify attestation information",
|
||||
Example: "validate <attestation> <report_data>",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Short: "Validate and verify attestation information. The report is provided as a file path.",
|
||||
Example: "validate <attestation_report_file_path>",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Println("Checking attestation")
|
||||
|
||||
if err := verifyAndValidateAttestation([]byte(args[0]), []byte(args[1])); err != nil {
|
||||
log.Fatalf("attestation validation and veification failed with error: %s", err)
|
||||
attestationFile = string(args[0])
|
||||
|
||||
if err := parseConfig(); err != nil {
|
||||
log.Fatalf("attestation validation and verification failed with error: %s", err)
|
||||
}
|
||||
if err := parseHashes(); err != nil {
|
||||
log.Fatalf("attestation validation and verification failed with error: %s", err)
|
||||
}
|
||||
if err := parseFiles(); err != nil {
|
||||
log.Fatalf("attestation validation and verification failed with error: %s", err)
|
||||
}
|
||||
// This format is the attestation report in AMD's specified ABI format, immediately
|
||||
// followed by the certificate table bytes.
|
||||
if len(attestation) < abi.ReportSize {
|
||||
log.Fatalf("attestation contents too small (0x%x bytes). Want at least 0x%x bytes", len(attestation), abi.ReportSize)
|
||||
}
|
||||
if err := parseUints(); err != nil {
|
||||
log.Fatalf("attestation validation and verification failed with error: %s", err)
|
||||
}
|
||||
cfg.Policy.Vmpl = wrapperspb.UInt32(0)
|
||||
|
||||
if err := validateInput(); err != nil {
|
||||
log.Fatalf("attestation validation and verification failed with error: %s", err)
|
||||
}
|
||||
|
||||
if err := verifyAndValidateAttestation(attestation); err != nil {
|
||||
log.Fatalf("attestation validation and verification failed with error: %s", err)
|
||||
}
|
||||
log.Println("Attestation validation and verification is successful!")
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(
|
||||
&cfgString,
|
||||
"config",
|
||||
"",
|
||||
"Serialized json check.Config protobuf. This will overwrite individual flags. Unmarshalled as json. Example: "+exampleJSONConfig,
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.HostData,
|
||||
"host_data",
|
||||
empty32[:],
|
||||
"The expected HOST_DATA field as a hex string. Must encode 32 bytes. Unchecked if unset.",
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.ReportData,
|
||||
"report_data",
|
||||
empty64[:],
|
||||
"The expected REPORT_DATA field as a hex string. Must encode 64 bytes. Must be set.",
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.FamilyId,
|
||||
"family_id",
|
||||
empty16[:],
|
||||
"The expected FAMILY_ID field as a hex string. Must encode 16 bytes. Unchecked if unset.",
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.ImageId,
|
||||
"image_id",
|
||||
empty16[:],
|
||||
"The expected IMAGE_ID field as a hex string. Must encode 16 bytes. Unchecked if unset.",
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.ReportId,
|
||||
"report_id",
|
||||
nil,
|
||||
"The expected REPORT_ID field as a hex string. Must encode 32 bytes. Unchecked if unset.",
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.ReportIdMa,
|
||||
"report_id_ma",
|
||||
defaultReportIdMa,
|
||||
"The expected REPORT_ID_MA field as a hex string. Must encode 32 bytes. Unchecked if unset.",
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.Measurement,
|
||||
"measurement",
|
||||
nil,
|
||||
"The expected MEASUREMENT field as a hex string. Must encode 48 bytes. Unchecked if unset.",
|
||||
)
|
||||
cmd.Flags().BytesHexVar(
|
||||
&cfg.Policy.ChipId,
|
||||
"chip_id",
|
||||
nil,
|
||||
"The expected MEASUREMENT field as a hex string. Must encode 48 bytes. Unchecked if unset.",
|
||||
)
|
||||
cmd.Flags().Uint64Var(
|
||||
&cfg.Policy.MinimumTcb,
|
||||
"minimum_tcb",
|
||||
defaultMinimumTcb,
|
||||
"The minimum acceptable value for CURRENT_TCB, COMMITTED_TCB, and REPORTED_TCB.",
|
||||
)
|
||||
cmd.Flags().Uint64Var(
|
||||
&cfg.Policy.MinimumLaunchTcb,
|
||||
"minimum_lauch_tcb",
|
||||
defaultMinimumLaunchTcb,
|
||||
"The minimum acceptable value for LAUNCH_TCB.",
|
||||
)
|
||||
cmd.Flags().Uint64Var(
|
||||
&cfg.Policy.Policy,
|
||||
"guest_policy",
|
||||
defaultGuestPolicy,
|
||||
"The most acceptable guest SnpPolicy.",
|
||||
)
|
||||
cmd.Flags().Uint32Var(
|
||||
&cfg.Policy.MinimumGuestSvn,
|
||||
"minimum_guest_svn",
|
||||
defaultMinimumGuestSvn,
|
||||
"The most acceptable GUEST_SVN.",
|
||||
)
|
||||
cmd.Flags().Uint32Var(
|
||||
&cfg.Policy.MinimumBuild,
|
||||
"minimum_build",
|
||||
defaultMinimumBuild,
|
||||
"The 8-bit minimum build number for AMD-SP firmware",
|
||||
)
|
||||
cmd.Flags().BoolVar(
|
||||
&cfg.RootOfTrust.CheckCrl,
|
||||
"check_crl",
|
||||
defaultCheckCrl,
|
||||
"Download and check the CRL for revoked certificates.",
|
||||
)
|
||||
cmd.Flags().DurationVar(
|
||||
&timeout,
|
||||
"timeout",
|
||||
defaultTimeout,
|
||||
"Duration to continue to retry failed HTTP requests.",
|
||||
)
|
||||
cmd.Flags().DurationVar(
|
||||
&maxRetryDelay,
|
||||
"max_retry_delay",
|
||||
defaultMaxRetryDelay,
|
||||
"Maximum Duration to wait between HTTP request retries.",
|
||||
)
|
||||
cmd.Flags().BoolVar(
|
||||
&cfg.Policy.RequireAuthorKey,
|
||||
"require_author_key",
|
||||
defaultRequireAuthor,
|
||||
"Require that AUTHOR_KEY_EN is 1.",
|
||||
)
|
||||
cmd.Flags().BoolVar(
|
||||
&cfg.Policy.RequireIdBlock,
|
||||
"require_id_block",
|
||||
defaultRequireIdBlock,
|
||||
"Require that the VM was launch with an ID_BLOCK signed by a trusted id key or author key",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&platformInfo,
|
||||
"platform_info",
|
||||
"",
|
||||
"The maximum acceptable PLATFORM_INFO field bit-wise. May be empty or a 64-bit unsigned integer",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&cfg.Policy.MinimumVersion,
|
||||
"minimum_version",
|
||||
defaultMinVersion,
|
||||
"Minimum AMD-SP firmware API version (major.minor). Each number must be 8-bit non-negative.",
|
||||
)
|
||||
cmd.Flags().StringArrayVar(
|
||||
&trustedAuthorKeys,
|
||||
"trusted_author_keys",
|
||||
[]string{},
|
||||
"Paths to x.509 certificates of trusted author keys",
|
||||
)
|
||||
cmd.Flags().StringArrayVar(
|
||||
&trustedAuthorHashes,
|
||||
"trusted_author_key_hashes",
|
||||
[]string{},
|
||||
"Hex-encoded SHA-384 hash values of trusted author keys in AMD public key format",
|
||||
)
|
||||
cmd.Flags().StringArrayVar(
|
||||
&trustedIdKeys,
|
||||
"trusted_id_keys",
|
||||
[]string{},
|
||||
"Paths to x.509 certificates of trusted author keys",
|
||||
)
|
||||
cmd.Flags().StringArrayVar(
|
||||
&trustedIdKeyHashes,
|
||||
"trusted_id_key_hashes",
|
||||
[]string{},
|
||||
"Hex-encoded SHA-384 hash values of trusted identity keys in AMD public key format",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&cfg.RootOfTrust.Product,
|
||||
"product",
|
||||
"",
|
||||
"The AMD product name for the chip that generated the attestation report.",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&stepping,
|
||||
"stepping",
|
||||
"",
|
||||
"The machine stepping for the chip that generated the attestation report. Default unchecked.",
|
||||
)
|
||||
cmd.Flags().StringArrayVar(
|
||||
&cfg.RootOfTrust.CabundlePaths,
|
||||
"CA_bundles_paths",
|
||||
[]string{},
|
||||
"Paths to CA bundles for the AMD product. Must be in PEM format, ASK, then ARK certificates. If unset, uses embedded root certificates.",
|
||||
)
|
||||
cmd.Flags().StringArrayVar(
|
||||
&cfg.RootOfTrust.Cabundles,
|
||||
"CA_bundles",
|
||||
[]string{},
|
||||
"PEM format CA bundles for the AMD product. Combined with contents of cabundle_paths.",
|
||||
)
|
||||
|
||||
if err := cmd.MarkFlagRequired("report_data"); err != nil {
|
||||
log.Fatalf("Failed to mark flag as required: %s", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func verifyAndValidateAttestation(attestation, reportData []byte) error {
|
||||
func verifyAndValidateAttestation(attestation []byte) error {
|
||||
sopts, err := verify.RootOfTrustToOptions(cfg.RootOfTrust)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sopts.Product = cfg.Policy.Product
|
||||
sopts.Getter = &trust.RetryHTTPSGetter{
|
||||
Timeout: timeout,
|
||||
MaxRetryDelay: maxRetryDelay,
|
||||
Getter: &trust.SimpleHTTPSGetter{},
|
||||
}
|
||||
attestationPB, err := abi.ReportCertsToProto(attestation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = verify.SnpAttestation(attestationPB, verify.DefaultOptions()); err != nil {
|
||||
if err = verify.SnpAttestation(attestationPB, sopts); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = validate.SnpAttestation(attestationPB, &validate.Options{ReportData: reportData}); err != nil {
|
||||
opts, err := validate.PolicyToOptions(cfg.Policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = validate.SnpAttestation(attestationPB, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseConfig decodes config passed as json for check.Config struct.
|
||||
// example
|
||||
/* {
|
||||
"rootOfTrust":{
|
||||
"product":"test_product",
|
||||
"cabundlePaths":[
|
||||
"test_cabundlePaths"
|
||||
],
|
||||
"cabundles":[
|
||||
"test_Cabundles"
|
||||
],
|
||||
"checkCrl":true,
|
||||
"disallowNetwork":true
|
||||
},
|
||||
"policy":{
|
||||
"minimumGuestSvn":1,
|
||||
"policy":"1",
|
||||
"familyId":"AQIDBAUGBwgJCgsMDQ4PEA==",
|
||||
"imageId":"AQIDBAUGBwgJCgsMDQ4PEA==",
|
||||
"vmpl":0,
|
||||
"minimumTcb":"1",
|
||||
"minimumLaunchTcb":"1",
|
||||
"platformInfo":"1",
|
||||
"requireAuthorKey":true,
|
||||
"reportData":"J+60aXs8btm8VcGgaJYURGeNCu0FIyWMFXQ7ZUlJDC0FJGJizJsOzDIXgQ75UtPC+Zqe0A3dvnnf5VEeQ61RTg==",
|
||||
"measurement":"8s78ewoX7Xkfy1qsgVnkZwLDotD768Nqt6qTL5wtQOxHsLczipKM6bhDmWiHLdP4",
|
||||
"hostData":"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw=",
|
||||
"reportId":"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw=",
|
||||
"reportIdMa":"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw=",
|
||||
"chipId":"J+60aXs8btm8VcGgaJYURGeNCu0FIyWMFXQ7ZUlJDC0FJGJizJsOzDIXgQ75UtPC+Zqe0A3dvnnf5VEeQ61RTg==",
|
||||
"minimumBuild":1,
|
||||
"minimumVersion":"0.90",
|
||||
"permitProvisionalFirmware":true,
|
||||
"requireIdBlock":true,
|
||||
"trustedAuthorKeys":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"trustedAuthorKeyHashes":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"trustedIdKeys":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"trustedIdKeyHashes":[
|
||||
"GSvLKpfu59Y9QOF6vhq0vQsOIvb4+5O/UOHLGLBTkdw="
|
||||
],
|
||||
"product":{
|
||||
"name":"SEV_PRODUCT_MILAN",
|
||||
"stepping":1,
|
||||
"machineStepping":1
|
||||
}
|
||||
}
|
||||
}*/
|
||||
func parseConfig() error {
|
||||
if cfgString == "" {
|
||||
return nil
|
||||
}
|
||||
if err := protojson.Unmarshal([]byte(cfgString), &cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
// Populate fields that should not be nil
|
||||
if cfg.RootOfTrust == nil {
|
||||
cfg.RootOfTrust = &check.RootOfTrust{}
|
||||
}
|
||||
if cfg.Policy == nil {
|
||||
cfg.Policy = &check.Policy{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseHashes() error {
|
||||
for _, hash := range trustedAuthorHashes {
|
||||
hashBytes, err := hex.DecodeString(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.TrustedAuthorKeyHashes = append(cfg.Policy.TrustedAuthorKeyHashes, hashBytes)
|
||||
}
|
||||
for _, hash := range trustedIdKeyHashes {
|
||||
hashBytes, err := hex.DecodeString(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.TrustedIdKeyHashes = append(cfg.Policy.TrustedIdKeyHashes, hashBytes)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseFiles() error {
|
||||
file, err := os.ReadFile(attestationFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
attestation = file
|
||||
for _, path := range trustedAuthorKeys {
|
||||
file, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.TrustedAuthorKeys = append(cfg.Policy.TrustedAuthorKeys, file)
|
||||
}
|
||||
for _, path := range trustedIdKeys {
|
||||
file, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.TrustedIdKeys = append(cfg.Policy.TrustedIdKeys, file)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseUints() error {
|
||||
if stepping != "" {
|
||||
if base := getBase(stepping); base == 10 {
|
||||
num, err := strconv.ParseUint(stepping, getBase(stepping), 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.Product.MachineStepping = wrapperspb.UInt32(uint32(num))
|
||||
} else {
|
||||
num, err := strconv.ParseUint(stepping[2:], base, 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.Product.MachineStepping = wrapperspb.UInt32(uint32(num))
|
||||
}
|
||||
}
|
||||
if platformInfo != "" {
|
||||
if base := getBase(platformInfo); base == 10 {
|
||||
num, err := strconv.ParseUint(platformInfo, getBase(platformInfo), 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.PlatformInfo = wrapperspb.UInt64(num)
|
||||
} else {
|
||||
num, err := strconv.ParseUint(platformInfo[2:], base, 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Policy.PlatformInfo = wrapperspb.UInt64(num)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getBase(val string) int {
|
||||
switch {
|
||||
case strings.HasPrefix(val, "0x"):
|
||||
return 16
|
||||
case strings.HasPrefix(val, "0o"):
|
||||
return 8
|
||||
case strings.HasPrefix(val, "0b"):
|
||||
return 2
|
||||
default:
|
||||
return 10
|
||||
}
|
||||
}
|
||||
|
||||
func validateInput() error {
|
||||
if len(cfg.RootOfTrust.CabundlePaths) != 0 || len(cfg.RootOfTrust.Cabundles) != 0 && cfg.RootOfTrust.Product == "" {
|
||||
return fmt.Errorf("product name must be set if CA bundles are provided")
|
||||
}
|
||||
|
||||
if err := validateFieldLength("report_data", cfg.Policy.ReportData, size64); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateFieldLength("host_data", cfg.Policy.HostData, size32); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateFieldLength("family_id", cfg.Policy.FamilyId, size16); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateFieldLength("image_id", cfg.Policy.ImageId, size16); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateFieldLength("report_id", cfg.Policy.ReportId, size32); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateFieldLength("report_id_ma", cfg.Policy.ReportIdMa, size32); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateFieldLength("measurement", cfg.Policy.Measurement, size48); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateFieldLength("chip_id", cfg.Policy.ChipId, size64); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, hash := range cfg.Policy.TrustedAuthorKeyHashes {
|
||||
if err := validateFieldLength("trusted_author_key_hash", hash, size48); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, hash := range cfg.Policy.TrustedIdKeyHashes {
|
||||
if err := validateFieldLength("trusted_id_key_hash", hash, size48); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateFieldLength(fieldName string, field []byte, expectedLength int) error {
|
||||
if field != nil && len(field) != expectedLength {
|
||||
return fmt.Errorf("%s length should be at least %d bytes long", fieldName, expectedLength)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -103,10 +103,6 @@ func main() {
|
||||
logger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
if err := pc.Send(&pkgmanager.ClientStreamMessage{Message: &pkgmanager.ClientStreamMessage_Whoami{}}); err != nil {
|
||||
logger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
eventsChan := make(chan *pkgmanager.ClientStreamMessage)
|
||||
svc := newService(logger, tracer, qemuCfg, eventsChan)
|
||||
|
||||
@@ -9,6 +9,7 @@ git clone git@github.com:ultravioletrs/cocos.git
|
||||
git clone git@github.com:buildroot/buildroot.git
|
||||
cd buildroot
|
||||
make BR2_EXTERNAL=../cocos/hal/linux cocos_defconfig
|
||||
# Execute 'make menuconfig' only if you want to make additional configuration changes to Buildroot.
|
||||
make menuconfig
|
||||
make
|
||||
```
|
||||
|
||||
@@ -168,7 +168,7 @@ func loadX509KeyPair(certfile, keyfile string) (tls.Certificate, error) {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
if _, err := os.Stat(keyfile); err == nil {
|
||||
cert, err = os.ReadFile(keyfile)
|
||||
key, err = os.ReadFile(keyfile)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
|
||||
+55
-13
@@ -43,8 +43,14 @@ sudo apt install qemu-kvm
|
||||
|
||||
Create `img` directory in `cmd/manager`. Create `tmp` directory in `cmd/manager`.
|
||||
|
||||
#### Add V-sock
|
||||
The necessary kernel modules must be loaded on the hypervisor.
|
||||
#### Add Vsock
|
||||
The necessary kernel modules must be loaded on the hypervisor. To check if `vhost_vsock` is loaded run:
|
||||
```shell
|
||||
lsmod | grep vhost_vsock
|
||||
```
|
||||
|
||||
If `vhost_vsock` is not loaded run the following commands:
|
||||
|
||||
```shell
|
||||
sudo modprobe vhost_vsock
|
||||
ls -l /dev/vhost-vsock
|
||||
@@ -53,7 +59,6 @@ ls -l /dev/vsock
|
||||
# crw-rw-rw- 1 root root 10, 121 Jan 16 12:05 /dev/vsock
|
||||
```
|
||||
|
||||
|
||||
### Prepare Cocos HAL
|
||||
|
||||
Cocos HAL for Linux is framework for building custom in-enclave Linux distribution. Use the instructions in [Readme](https://github.com/ultravioletrs/cocos/blob/main/hal/linux/README.md).
|
||||
@@ -96,6 +101,7 @@ qemu-system-x86_64 \
|
||||
Once the VM is booted press enter and on the login use username `root`.
|
||||
|
||||
#### Build and run Agent
|
||||
|
||||
Agent is started automatically in the VM.
|
||||
```sh
|
||||
# List running processes and use 'grep' to filter for processes containing 'agent' in their names.
|
||||
@@ -138,21 +144,18 @@ NB: we set environment variables that we will use in the shell process where we
|
||||
|
||||
## Deployment
|
||||
|
||||
To start the service, execute the following shell script (note a server needs to be running see [here](../test/manager-server/README.md)):
|
||||
To start the service, execute the following shell script (note a server needs to be running see [here](../test/computations/README.md)):
|
||||
|
||||
```bash
|
||||
# download the latest version of the service
|
||||
go get github.com/ultravioletrs/cocos
|
||||
# Download the latest version of the service
|
||||
git clone git@github.com:ultravioletrs/cocos.git
|
||||
|
||||
cd $GOPATH/src/github.com/ultravioletrs/cocos
|
||||
cd cocos
|
||||
|
||||
# compile the manager
|
||||
# Compile the manager
|
||||
make manager
|
||||
|
||||
# copy binary to bin
|
||||
make install
|
||||
|
||||
# set the environment variables and run the service
|
||||
# Set the environment variables and run the service
|
||||
MANAGER_GRPC_URL=localhost:7001
|
||||
MANAGER_LOG_LEVEL=debug \
|
||||
MANAGER_QEMU_USE_SUDO=false \
|
||||
@@ -171,9 +174,48 @@ MANAGER_QEMU_SEV_CBITPOS=51 \
|
||||
./build/cocos-manager
|
||||
```
|
||||
|
||||
The kernel hash feature might not work with the current build of OVMF and QEMU. If so, build the host kernel, QEMU, and OVMF from the [AMD SEV GitHub](https://github.com/AMDESE/AMDSEV/tree/snp-latest) repository.
|
||||
|
||||
To enable [AMD SEV-SNP](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_ENABLE_SEV=false \
|
||||
MANAGER_QEMU_ENABLE_SEV_SNP=true \
|
||||
MANAGER_QEMU_SEV_CBITPOS=51 \
|
||||
MANAGER_QEMU_BIN_PATH=<path to QEMU binary> \
|
||||
MANAGER_QEMU_QEMU_OVMF_CODE_FILE=<path to OVMF Amd Sev built package> \
|
||||
./build/cocos-manager
|
||||
```
|
||||
|
||||
To include the kernel hash into the measurement of the attestation report (SEV or SEV-SNP), start manager like this
|
||||
|
||||
```sh
|
||||
MANAGER_GRPC_URL=localhost:7001 \
|
||||
MANAGER_LOG_LEVEL=debug \
|
||||
MANAGER_QEMU_ENABLE_SEV=false \
|
||||
MANAGER_QEMU_ENABLE_SEV_SNP=true \
|
||||
MANAGER_QEMU_SEV_CBITPOS=51 \
|
||||
MANAGER_QEMU_KERNEL_HASH=true \
|
||||
./build/cocos-manager
|
||||
```
|
||||
|
||||
### 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.
|
||||
NB: To verify that the manager successfully launched the VM, you need to open three terminals on the same machine. In one terminal, you need to launch the Manager test server by executing (with the environment variables of choice):
|
||||
|
||||
```bash
|
||||
go run ./test/manager-server/main.go
|
||||
```
|
||||
|
||||
and in the second the manager by executing (with the environment variables of choice):
|
||||
|
||||
```bash
|
||||
go run ./cmd/manager/main.go
|
||||
```
|
||||
|
||||
Ensure that the Manager can connect to the Manager test server by setting the MANAGER_GRPC_PORT with the port value of the Manager test server. The Manager test server is listening on the default value of the MANAGER_GRPC_PORT. In the last one, you can run the verification commands.
|
||||
|
||||
To verify that the manager launched the VM successfully, run the following command:
|
||||
|
||||
|
||||
@@ -31,20 +31,19 @@ func NewServer(ctx context.Context, incoming chan *manager.ClientStreamMessage,
|
||||
}
|
||||
|
||||
func (s *grpcServer) Process(stream manager.ManagerService_ProcessServer) error {
|
||||
eg, _ := errgroup.WithContext(s.ctx)
|
||||
runReqChan := make(chan *manager.ComputationRunReq)
|
||||
client, ok := peer.FromContext(stream.Context())
|
||||
if ok {
|
||||
go s.svc.Run(client.Addr.String(), runReqChan)
|
||||
}
|
||||
eg, _ := errgroup.WithContext(s.ctx)
|
||||
|
||||
eg.Go(func() error {
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := req.Message.(*manager.ClientStreamMessage_Whoami); ok {
|
||||
client, ok := peer.FromContext(stream.Context())
|
||||
if ok {
|
||||
s.svc.Run(client.Addr.String(), runReqChan)
|
||||
}
|
||||
}
|
||||
|
||||
s.incoming <- req
|
||||
}
|
||||
|
||||
@@ -13,9 +13,6 @@ service ManagerService {
|
||||
rpc Process(stream ClientStreamMessage) returns (stream ComputationRunReq) {}
|
||||
}
|
||||
|
||||
message WhoAmI {
|
||||
}
|
||||
|
||||
message RunResponse{
|
||||
string agent_port = 1;
|
||||
string computation_id = 2;
|
||||
@@ -39,10 +36,9 @@ message AgentLog {
|
||||
|
||||
message ClientStreamMessage {
|
||||
oneof message {
|
||||
WhoAmI whoami = 1;
|
||||
AgentLog agent_log = 2;
|
||||
AgentEvent agent_event = 3;
|
||||
RunResponse run_res = 4;
|
||||
AgentLog agent_log = 1;
|
||||
AgentEvent agent_event = 2;
|
||||
RunResponse run_res = 3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,13 +55,13 @@ message ComputationRunReq {
|
||||
message Dataset {
|
||||
string provider = 1;
|
||||
string id = 2;
|
||||
bytes hash = 3;
|
||||
bytes hash = 3; // should be sha3.Sum256, 32 byte length.
|
||||
}
|
||||
|
||||
message Algorithm {
|
||||
string provider = 1;
|
||||
string id = 2;
|
||||
bytes hash = 3;
|
||||
bytes hash = 3; // should be sha3.Sum256, 32 byte length.
|
||||
}
|
||||
|
||||
message AgentConfig {
|
||||
|
||||
+47
-15
@@ -59,19 +59,25 @@ type VSockConfig struct {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
TmpFileLoc string `env:"TMP_FILE_LOC" envDefault:"tmp"`
|
||||
UseSudo bool `env:"USE_SUDO" envDefault:"false"`
|
||||
EnableSEV bool `env:"ENABLE_SEV" envDefault:"true"`
|
||||
QemuBinPath string `env:"BIN_PATH" envDefault:"qemu-system-x86_64"`
|
||||
TmpFileLoc string `env:"TMP_FILE_LOC" envDefault:"tmp"`
|
||||
UseSudo bool `env:"USE_SUDO" envDefault:"false"`
|
||||
EnableSEV bool `env:"ENABLE_SEV" envDefault:"false"`
|
||||
EnableSEVSNP bool `env:"ENABLE_SEV_SNP" envDefault:"true"`
|
||||
|
||||
EnableKVM bool `env:"ENABLE_KVM" envDefault:"true"`
|
||||
|
||||
// machine, CPU, RAM
|
||||
Machine string `env:"MACHINE" envDefault:"q35"`
|
||||
CPU string `env:"CPU" envDefault:"EPYC"`
|
||||
SmpCount int `env:"SMP_COUNT" envDefault:"4"`
|
||||
MaxCpus int `env:"SMP_MAXCPUS" envDefault:"64"`
|
||||
SMPCount int `env:"SMP_COUNT" envDefault:"4"`
|
||||
MaxCPUs int `env:"SMP_MAXCPUS" envDefault:"64"`
|
||||
MemID string `env:"MEM_ID" envDefault:"ram1"`
|
||||
MemoryConfig
|
||||
|
||||
// Kernel hash
|
||||
KernelHash bool `env:"KERNEL_HASH" envDefault:"false"`
|
||||
|
||||
// OVMF
|
||||
OVMFCodeConfig
|
||||
OVMFVarsConfig
|
||||
@@ -111,7 +117,7 @@ func constructQemuArgs(config Config) []string {
|
||||
args = append(args, "-cpu", config.CPU)
|
||||
}
|
||||
|
||||
args = append(args, "-smp", fmt.Sprintf("%d,maxcpus=%d", config.SmpCount, config.MaxCpus))
|
||||
args = append(args, "-smp", fmt.Sprintf("%d,maxcpus=%d", config.SMPCount, config.MaxCPUs))
|
||||
|
||||
args = append(args, "-m", fmt.Sprintf("%s,slots=%d,maxmem=%s",
|
||||
config.MemoryConfig.Size,
|
||||
@@ -127,12 +133,14 @@ func constructQemuArgs(config Config) []string {
|
||||
config.OVMFCodeConfig.File,
|
||||
config.OVMFCodeConfig.ReadOnly))
|
||||
|
||||
args = append(args, "-drive",
|
||||
fmt.Sprintf("if=%s,format=%s,unit=%d,file=%s",
|
||||
config.OVMFVarsConfig.If,
|
||||
config.OVMFVarsConfig.Format,
|
||||
config.OVMFVarsConfig.Unit,
|
||||
config.OVMFVarsConfig.File))
|
||||
if !config.KernelHash {
|
||||
args = append(args, "-drive",
|
||||
fmt.Sprintf("if=%s,format=%s,unit=%d,file=%s",
|
||||
config.OVMFVarsConfig.If,
|
||||
config.OVMFVarsConfig.Format,
|
||||
config.OVMFVarsConfig.Unit,
|
||||
config.OVMFVarsConfig.File))
|
||||
}
|
||||
|
||||
// network
|
||||
args = append(args, "-netdev",
|
||||
@@ -150,17 +158,41 @@ func constructQemuArgs(config Config) []string {
|
||||
|
||||
args = append(args, "-device", fmt.Sprintf("vhost-vsock-pci,id=%s,guest-cid=%d", config.VSockConfig.ID, config.VSockConfig.GuestCID))
|
||||
args = append(args, "-vnc", fmt.Sprintf(":%d", config.vnc))
|
||||
|
||||
if config.EnableSEVSNP {
|
||||
args = append(args, "-object",
|
||||
fmt.Sprintf("memory-backend-memfd-private,id=%s,size=%s,share=true",
|
||||
config.MemID,
|
||||
config.MemoryConfig.Size))
|
||||
args = append(args, "-machine",
|
||||
fmt.Sprintf("memory-backend=%s,kvm-type=protected",
|
||||
config.MemID))
|
||||
}
|
||||
|
||||
args = append(args, "-kernel", config.DiskImgConfig.KernelFile)
|
||||
args = append(args, "-append", strconv.Quote("earlyprintk=serial console=ttyS0"))
|
||||
args = append(args, "-initrd", config.DiskImgConfig.RootFsFile)
|
||||
|
||||
// SEV
|
||||
if config.EnableSEV {
|
||||
if config.EnableSEV || config.EnableSEVSNP {
|
||||
sevType := "sev-guest"
|
||||
kernelHash := ""
|
||||
|
||||
if config.EnableSEVSNP {
|
||||
sevType = "sev-snp-guest"
|
||||
}
|
||||
|
||||
if config.KernelHash {
|
||||
kernelHash = ",discard=none,kernel-hashes=on"
|
||||
}
|
||||
|
||||
args = append(args, "-object",
|
||||
fmt.Sprintf("sev-guest,id=%s,cbitpos=%d,reduced-phys-bits=%d",
|
||||
fmt.Sprintf("%s,id=%s,cbitpos=%d,reduced-phys-bits=%d%s",
|
||||
sevType,
|
||||
config.SevConfig.ID,
|
||||
config.SevConfig.CBitPos,
|
||||
config.SevConfig.ReducedPhysBits))
|
||||
config.SevConfig.ReducedPhysBits,
|
||||
kernelHash))
|
||||
|
||||
args = append(args, "-machine",
|
||||
fmt.Sprintf("memory-encryption=%s", config.SevConfig.ID))
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
qemuRelPath = "qemu-system-x86_64"
|
||||
firmwareVars = "OVMF_VARS"
|
||||
KernelFile = "bzImage"
|
||||
rootfsFile = "rootfs.cpio"
|
||||
@@ -67,7 +66,7 @@ func CreateVM(ctx context.Context, cfg Config) (*exec.Cmd, error) {
|
||||
}
|
||||
|
||||
func ExecutableAndArgs(cfg Config) (string, []string, error) {
|
||||
exe, err := exec.LookPath(qemuRelPath)
|
||||
exe, err := exec.LookPath(cfg.QemuBinPath)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
+154
-224
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v4.25.1
|
||||
// protoc v4.25.3
|
||||
// source: manager/manager.proto
|
||||
|
||||
package manager
|
||||
@@ -24,44 +24,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type WhoAmI struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *WhoAmI) Reset() {
|
||||
*x = WhoAmI{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *WhoAmI) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*WhoAmI) ProtoMessage() {}
|
||||
|
||||
func (x *WhoAmI) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use WhoAmI.ProtoReflect.Descriptor instead.
|
||||
func (*WhoAmI) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type RunResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -74,7 +36,7 @@ type RunResponse struct {
|
||||
func (x *RunResponse) Reset() {
|
||||
*x = RunResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -87,7 +49,7 @@ func (x *RunResponse) String() string {
|
||||
func (*RunResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RunResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -100,7 +62,7 @@ func (x *RunResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RunResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RunResponse) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{1}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RunResponse) GetAgentPort() string {
|
||||
@@ -133,7 +95,7 @@ type AgentEvent struct {
|
||||
func (x *AgentEvent) Reset() {
|
||||
*x = AgentEvent{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -146,7 +108,7 @@ func (x *AgentEvent) String() string {
|
||||
func (*AgentEvent) ProtoMessage() {}
|
||||
|
||||
func (x *AgentEvent) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -159,7 +121,7 @@ func (x *AgentEvent) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AgentEvent.ProtoReflect.Descriptor instead.
|
||||
func (*AgentEvent) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{2}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *AgentEvent) GetEventType() string {
|
||||
@@ -218,7 +180,7 @@ type AgentLog struct {
|
||||
func (x *AgentLog) Reset() {
|
||||
*x = AgentLog{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -231,7 +193,7 @@ func (x *AgentLog) String() string {
|
||||
func (*AgentLog) ProtoMessage() {}
|
||||
|
||||
func (x *AgentLog) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -244,7 +206,7 @@ func (x *AgentLog) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AgentLog.ProtoReflect.Descriptor instead.
|
||||
func (*AgentLog) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{3}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *AgentLog) GetMessage() string {
|
||||
@@ -282,7 +244,6 @@ type ClientStreamMessage struct {
|
||||
|
||||
// Types that are assignable to Message:
|
||||
//
|
||||
// *ClientStreamMessage_Whoami
|
||||
// *ClientStreamMessage_AgentLog
|
||||
// *ClientStreamMessage_AgentEvent
|
||||
// *ClientStreamMessage_RunRes
|
||||
@@ -292,7 +253,7 @@ type ClientStreamMessage struct {
|
||||
func (x *ClientStreamMessage) Reset() {
|
||||
*x = ClientStreamMessage{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -305,7 +266,7 @@ func (x *ClientStreamMessage) String() string {
|
||||
func (*ClientStreamMessage) ProtoMessage() {}
|
||||
|
||||
func (x *ClientStreamMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -318,7 +279,7 @@ func (x *ClientStreamMessage) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ClientStreamMessage.ProtoReflect.Descriptor instead.
|
||||
func (*ClientStreamMessage) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{4}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (m *ClientStreamMessage) GetMessage() isClientStreamMessage_Message {
|
||||
@@ -328,13 +289,6 @@ func (m *ClientStreamMessage) GetMessage() isClientStreamMessage_Message {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ClientStreamMessage) GetWhoami() *WhoAmI {
|
||||
if x, ok := x.GetMessage().(*ClientStreamMessage_Whoami); ok {
|
||||
return x.Whoami
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ClientStreamMessage) GetAgentLog() *AgentLog {
|
||||
if x, ok := x.GetMessage().(*ClientStreamMessage_AgentLog); ok {
|
||||
return x.AgentLog
|
||||
@@ -360,24 +314,18 @@ type isClientStreamMessage_Message interface {
|
||||
isClientStreamMessage_Message()
|
||||
}
|
||||
|
||||
type ClientStreamMessage_Whoami struct {
|
||||
Whoami *WhoAmI `protobuf:"bytes,1,opt,name=whoami,proto3,oneof"`
|
||||
}
|
||||
|
||||
type ClientStreamMessage_AgentLog struct {
|
||||
AgentLog *AgentLog `protobuf:"bytes,2,opt,name=agent_log,json=agentLog,proto3,oneof"`
|
||||
AgentLog *AgentLog `protobuf:"bytes,1,opt,name=agent_log,json=agentLog,proto3,oneof"`
|
||||
}
|
||||
|
||||
type ClientStreamMessage_AgentEvent struct {
|
||||
AgentEvent *AgentEvent `protobuf:"bytes,3,opt,name=agent_event,json=agentEvent,proto3,oneof"`
|
||||
AgentEvent *AgentEvent `protobuf:"bytes,2,opt,name=agent_event,json=agentEvent,proto3,oneof"`
|
||||
}
|
||||
|
||||
type ClientStreamMessage_RunRes struct {
|
||||
RunRes *RunResponse `protobuf:"bytes,4,opt,name=run_res,json=runRes,proto3,oneof"`
|
||||
RunRes *RunResponse `protobuf:"bytes,3,opt,name=run_res,json=runRes,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*ClientStreamMessage_Whoami) isClientStreamMessage_Message() {}
|
||||
|
||||
func (*ClientStreamMessage_AgentLog) isClientStreamMessage_Message() {}
|
||||
|
||||
func (*ClientStreamMessage_AgentEvent) isClientStreamMessage_Message() {}
|
||||
@@ -401,7 +349,7 @@ type ComputationRunReq struct {
|
||||
func (x *ComputationRunReq) Reset() {
|
||||
*x = ComputationRunReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -414,7 +362,7 @@ func (x *ComputationRunReq) String() string {
|
||||
func (*ComputationRunReq) ProtoMessage() {}
|
||||
|
||||
func (x *ComputationRunReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -427,7 +375,7 @@ func (x *ComputationRunReq) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ComputationRunReq.ProtoReflect.Descriptor instead.
|
||||
func (*ComputationRunReq) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{5}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ComputationRunReq) GetId() string {
|
||||
@@ -486,13 +434,13 @@ type Dataset struct {
|
||||
|
||||
Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Hash []byte `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"`
|
||||
Hash []byte `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` // should be sha3.Sum256, 32 byte length.
|
||||
}
|
||||
|
||||
func (x *Dataset) Reset() {
|
||||
*x = Dataset{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[6]
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -505,7 +453,7 @@ func (x *Dataset) String() string {
|
||||
func (*Dataset) ProtoMessage() {}
|
||||
|
||||
func (x *Dataset) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[6]
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -518,7 +466,7 @@ func (x *Dataset) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Dataset.ProtoReflect.Descriptor instead.
|
||||
func (*Dataset) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{6}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *Dataset) GetProvider() string {
|
||||
@@ -549,13 +497,13 @@ type Algorithm struct {
|
||||
|
||||
Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Hash []byte `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"`
|
||||
Hash []byte `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` // should be sha3.Sum256, 32 byte length.
|
||||
}
|
||||
|
||||
func (x *Algorithm) Reset() {
|
||||
*x = Algorithm{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[7]
|
||||
mi := &file_manager_manager_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -568,7 +516,7 @@ func (x *Algorithm) String() string {
|
||||
func (*Algorithm) ProtoMessage() {}
|
||||
|
||||
func (x *Algorithm) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[7]
|
||||
mi := &file_manager_manager_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -581,7 +529,7 @@ func (x *Algorithm) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Algorithm.ProtoReflect.Descriptor instead.
|
||||
func (*Algorithm) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{7}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *Algorithm) GetProvider() string {
|
||||
@@ -622,7 +570,7 @@ type AgentConfig struct {
|
||||
func (x *AgentConfig) Reset() {
|
||||
*x = AgentConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_manager_manager_proto_msgTypes[8]
|
||||
mi := &file_manager_manager_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -635,7 +583,7 @@ func (x *AgentConfig) String() string {
|
||||
func (*AgentConfig) ProtoMessage() {}
|
||||
|
||||
func (x *AgentConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[8]
|
||||
mi := &file_manager_manager_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -648,7 +596,7 @@ func (x *AgentConfig) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AgentConfig.ProtoReflect.Descriptor instead.
|
||||
func (*AgentConfig) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{8}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *AgentConfig) GetPort() string {
|
||||
@@ -707,99 +655,96 @@ var file_manager_manager_proto_rawDesc = []byte{
|
||||
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, 0x08, 0x0a, 0x06, 0x57, 0x68, 0x6f, 0x41, 0x6d, 0x49, 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, 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,
|
||||
0xe6, 0x01, 0x0a, 0x13, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x77, 0x68, 0x6f, 0x61, 0x6d,
|
||||
0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||
0x72, 0x2e, 0x57, 0x68, 0x6f, 0x41, 0x6d, 0x49, 0x48, 0x00, 0x52, 0x06, 0x77, 0x68, 0x6f, 0x61,
|
||||
0x6d, 0x69, 0x12, 0x30, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x18,
|
||||
0x02, 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, 0x03, 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, 0x04, 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, 0x42, 0x09, 0x0a,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9f, 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, 0x32, 0x0a, 0x0a, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x73,
|
||||
0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||
0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x0a, 0x61, 0x6c, 0x67, 0x6f,
|
||||
0x72, 0x69, 0x74, 0x68, 0x6d, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09,
|
||||
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, 0x49, 0x0a, 0x07, 0x44, 0x61,
|
||||
0x74, 0x61, 0x73, 0x65, 0x74, 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, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x4b, 0x0a, 0x09, 0x41, 0x6c, 0x67, 0x6f, 0x72, 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, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61,
|
||||
0x73, 0x68, 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, 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, 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,
|
||||
0x6f, 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, 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, 0xbb, 0x01, 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, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x22, 0x9f, 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, 0x32, 0x0a,
|
||||
0x0a, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x41, 0x6c, 0x67, 0x6f,
|
||||
0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x0a, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d,
|
||||
0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 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, 0x49, 0x0a, 0x07, 0x44, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74,
|
||||
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, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68,
|
||||
0x22, 0x4b, 0x0a, 0x09, 0x41, 0x6c, 0x67, 0x6f, 0x72, 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, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73,
|
||||
0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 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, 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, 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 (
|
||||
@@ -814,36 +759,34 @@ func file_manager_manager_proto_rawDescGZIP() []byte {
|
||||
return file_manager_manager_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_manager_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_manager_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_manager_manager_proto_goTypes = []interface{}{
|
||||
(*WhoAmI)(nil), // 0: manager.WhoAmI
|
||||
(*RunResponse)(nil), // 1: manager.RunResponse
|
||||
(*AgentEvent)(nil), // 2: manager.AgentEvent
|
||||
(*AgentLog)(nil), // 3: manager.AgentLog
|
||||
(*ClientStreamMessage)(nil), // 4: manager.ClientStreamMessage
|
||||
(*ComputationRunReq)(nil), // 5: manager.ComputationRunReq
|
||||
(*Dataset)(nil), // 6: manager.Dataset
|
||||
(*Algorithm)(nil), // 7: manager.Algorithm
|
||||
(*AgentConfig)(nil), // 8: manager.AgentConfig
|
||||
(*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp
|
||||
(*RunResponse)(nil), // 0: manager.RunResponse
|
||||
(*AgentEvent)(nil), // 1: manager.AgentEvent
|
||||
(*AgentLog)(nil), // 2: manager.AgentLog
|
||||
(*ClientStreamMessage)(nil), // 3: manager.ClientStreamMessage
|
||||
(*ComputationRunReq)(nil), // 4: manager.ComputationRunReq
|
||||
(*Dataset)(nil), // 5: manager.Dataset
|
||||
(*Algorithm)(nil), // 6: manager.Algorithm
|
||||
(*AgentConfig)(nil), // 7: manager.AgentConfig
|
||||
(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
|
||||
}
|
||||
var file_manager_manager_proto_depIdxs = []int32{
|
||||
9, // 0: manager.AgentEvent.timestamp:type_name -> google.protobuf.Timestamp
|
||||
9, // 1: manager.AgentLog.timestamp:type_name -> google.protobuf.Timestamp
|
||||
0, // 2: manager.ClientStreamMessage.whoami:type_name -> manager.WhoAmI
|
||||
3, // 3: manager.ClientStreamMessage.agent_log:type_name -> manager.AgentLog
|
||||
2, // 4: manager.ClientStreamMessage.agent_event:type_name -> manager.AgentEvent
|
||||
1, // 5: manager.ClientStreamMessage.run_res:type_name -> manager.RunResponse
|
||||
6, // 6: manager.ComputationRunReq.datasets:type_name -> manager.Dataset
|
||||
7, // 7: manager.ComputationRunReq.algorithms:type_name -> manager.Algorithm
|
||||
8, // 8: manager.ComputationRunReq.agent_config:type_name -> manager.AgentConfig
|
||||
4, // 9: manager.ManagerService.Process:input_type -> manager.ClientStreamMessage
|
||||
5, // 10: manager.ManagerService.Process:output_type -> manager.ComputationRunReq
|
||||
10, // [10:11] is the sub-list for method output_type
|
||||
9, // [9:10] is the sub-list for method input_type
|
||||
9, // [9:9] is the sub-list for extension type_name
|
||||
9, // [9:9] is the sub-list for extension extendee
|
||||
0, // [0:9] is the sub-list for field type_name
|
||||
8, // 0: manager.AgentEvent.timestamp:type_name -> google.protobuf.Timestamp
|
||||
8, // 1: manager.AgentLog.timestamp:type_name -> google.protobuf.Timestamp
|
||||
2, // 2: manager.ClientStreamMessage.agent_log:type_name -> manager.AgentLog
|
||||
1, // 3: manager.ClientStreamMessage.agent_event:type_name -> manager.AgentEvent
|
||||
0, // 4: manager.ClientStreamMessage.run_res:type_name -> manager.RunResponse
|
||||
5, // 5: manager.ComputationRunReq.datasets:type_name -> manager.Dataset
|
||||
6, // 6: manager.ComputationRunReq.algorithms:type_name -> manager.Algorithm
|
||||
7, // 7: manager.ComputationRunReq.agent_config:type_name -> manager.AgentConfig
|
||||
3, // 8: manager.ManagerService.Process:input_type -> manager.ClientStreamMessage
|
||||
4, // 9: manager.ManagerService.Process:output_type -> manager.ComputationRunReq
|
||||
9, // [9:10] is the sub-list for method output_type
|
||||
8, // [8:9] is the sub-list for method input_type
|
||||
8, // [8:8] is the sub-list for extension type_name
|
||||
8, // [8:8] is the sub-list for extension extendee
|
||||
0, // [0:8] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_manager_manager_proto_init() }
|
||||
@@ -853,18 +796,6 @@ func file_manager_manager_proto_init() {
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_manager_manager_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*WhoAmI); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RunResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -876,7 +807,7 @@ func file_manager_manager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_manager_manager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AgentEvent); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -888,7 +819,7 @@ func file_manager_manager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_manager_manager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AgentLog); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -900,7 +831,7 @@ func file_manager_manager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_manager_manager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ClientStreamMessage); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -912,7 +843,7 @@ func file_manager_manager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_manager_manager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ComputationRunReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -924,7 +855,7 @@ func file_manager_manager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_manager_manager_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Dataset); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -936,7 +867,7 @@ func file_manager_manager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_manager_manager_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Algorithm); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -948,7 +879,7 @@ func file_manager_manager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_manager_manager_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AgentConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -961,8 +892,7 @@ func file_manager_manager_proto_init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
file_manager_manager_proto_msgTypes[4].OneofWrappers = []interface{}{
|
||||
(*ClientStreamMessage_Whoami)(nil),
|
||||
file_manager_manager_proto_msgTypes[3].OneofWrappers = []interface{}{
|
||||
(*ClientStreamMessage_AgentLog)(nil),
|
||||
(*ClientStreamMessage_AgentEvent)(nil),
|
||||
(*ClientStreamMessage_RunRes)(nil),
|
||||
@@ -973,7 +903,7 @@ func file_manager_manager_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_manager_manager_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 9,
|
||||
NumMessages: 8,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v4.25.1
|
||||
// - protoc v4.25.3
|
||||
// source: manager/manager.proto
|
||||
|
||||
package manager
|
||||
|
||||
+4
-2
@@ -11,6 +11,8 @@ import (
|
||||
|
||||
var _ agent.Service = (*agentSDK)(nil)
|
||||
|
||||
const size64 = 64
|
||||
|
||||
type agentSDK struct {
|
||||
client agent.AgentServiceClient
|
||||
logger *slog.Logger
|
||||
@@ -67,9 +69,9 @@ func (sdk *agentSDK) Result(ctx context.Context, consumer string) ([]byte, error
|
||||
return response.File, nil
|
||||
}
|
||||
|
||||
func (sdk *agentSDK) Attestation(ctx context.Context, reportData []byte) ([]byte, error) {
|
||||
func (sdk *agentSDK) Attestation(ctx context.Context, reportData [size64]byte) ([]byte, error) {
|
||||
request := &agent.AttestationRequest{
|
||||
ReportData: reportData,
|
||||
ReportData: reportData[:],
|
||||
}
|
||||
|
||||
response, err := sdk.client.Attestation(ctx, request)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Manager test server
|
||||
Manager service is a grpc client. It connects to a server and sends a whoAmIRequest.
|
||||
# Computations Server
|
||||
Manager service is a grpc client. It connects to computations server.
|
||||
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
|
||||
@@ -8,12 +8,12 @@ The service is configured using the environment variables from the following tab
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ---------------- | ---------------------------------------- | ------- |
|
||||
| HOST | Manager service gRPC host | |
|
||||
| PORT | Manager service gRPC port | 7001 |
|
||||
| HOST | Computations service gRPC host | |
|
||||
| PORT | Computations 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
|
||||
go run main.go <dataset_path> <algo_path>
|
||||
```
|
||||
@@ -4,7 +4,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
@@ -16,6 +15,7 @@ import (
|
||||
grpcserver "github.com/ultravioletrs/cocos/internal/server/grpc"
|
||||
managergrpc "github.com/ultravioletrs/cocos/manager/api/grpc"
|
||||
"github.com/ultravioletrs/cocos/pkg/manager"
|
||||
"golang.org/x/crypto/sha3"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
@@ -28,19 +28,35 @@ const (
|
||||
defaultPort = "7001"
|
||||
)
|
||||
|
||||
var (
|
||||
algoPath = "./test/manual/algo/lin_reg.py"
|
||||
dataPath = "./test/manual/data/iris.csv"
|
||||
)
|
||||
|
||||
type svc struct {
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (s *svc) Run(ipAdress string, reqChan chan *manager.ComputationRunReq) {
|
||||
s.logger.Debug(fmt.Sprintf("received who am on ip address %s", ipAdress))
|
||||
hash := sha256.Sum256([]byte("test"))
|
||||
algo, err := os.ReadFile(algoPath)
|
||||
if err != nil {
|
||||
s.logger.Error(fmt.Sprintf("failed to read algorithm file: %s", err))
|
||||
return
|
||||
}
|
||||
data, err := os.ReadFile(dataPath)
|
||||
if err != nil {
|
||||
s.logger.Error(fmt.Sprintf("failed to read data file: %s", err))
|
||||
return
|
||||
}
|
||||
algoHash := sha3.Sum256(algo)
|
||||
dataHash := sha3.Sum256(data)
|
||||
reqChan <- &manager.ComputationRunReq{
|
||||
Id: "1",
|
||||
Name: "sample computation",
|
||||
Description: "sample descrption",
|
||||
Datasets: []*manager.Dataset{{Id: "1", Provider: "provider1", Hash: hash[:]}},
|
||||
Algorithms: []*manager.Algorithm{{Id: "1", Provider: "provider1", Hash: hash[:]}},
|
||||
Datasets: []*manager.Dataset{{Id: "1", Provider: "provider1", Hash: dataHash[:]}},
|
||||
Algorithms: []*manager.Algorithm{{Id: "1", Provider: "provider1", Hash: algoHash[:]}},
|
||||
ResultConsumers: []string{"consumer1"},
|
||||
AgentConfig: &manager.AgentConfig{
|
||||
Port: "7002",
|
||||
@@ -50,6 +66,11 @@ func (s *svc) Run(ipAdress string, reqChan chan *manager.ComputationRunReq) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 3 {
|
||||
log.Fatalf("usage: %s <data-path> <algo-path>", os.Args[0])
|
||||
}
|
||||
dataPath = os.Args[1]
|
||||
algoPath = os.Args[2]
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
incomingChan := make(chan *manager.ClientStreamMessage)
|
||||
@@ -62,8 +83,6 @@ func main() {
|
||||
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:
|
||||
@@ -28,7 +28,7 @@ export MANAGER_GRPC_URL=localhost:7001
|
||||
go run cmd/cli/main.go attestation get '<report_data>'
|
||||
|
||||
# Validate Attestation
|
||||
go run cmd/cli/main.go attestation validate '<attesation>' '<report_data>'
|
||||
go run cmd/cli/main.go attestation validate '<attesation>' --report_data '<report_data>'
|
||||
|
||||
# Run the CLI program with algorithm input
|
||||
go run cmd/cli/main.go algo test/manual/algo/lin_reg.py Algorithm1 AlgorithmProvider1
|
||||
|
||||
@@ -85,27 +85,25 @@ func main() {
|
||||
}
|
||||
fmt.Println(SendAgentConfig(3, ac))
|
||||
|
||||
go func() {
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
b := make([]byte, 1024)
|
||||
n, err := conn.Read(b)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
conn.Close()
|
||||
var mes manager.ClientStreamMessage
|
||||
if err := proto.Unmarshal(b[:n], &mes); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
fmt.Println(mes.String())
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
}()
|
||||
b := make([]byte, 1024)
|
||||
n, err := conn.Read(b)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
conn.Close()
|
||||
var mes manager.ClientStreamMessage
|
||||
if err := proto.Unmarshal(b[:n], &mes); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
fmt.Println(mes.String())
|
||||
}
|
||||
}
|
||||
|
||||
func SendAgentConfig(cid uint32, ac Computation) error {
|
||||
|
||||
Reference in New Issue
Block a user