mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-23 04:10:25 +00:00
NOISSUE - Set env automatically (#355)
* new agent structure Signed-off-by: Sammy Oina <sammyoina@gmail.com> * fix lint Signed-off-by: Sammy Oina <sammyoina@gmail.com> * fix tests Signed-off-by: Sammy Oina <sammyoina@gmail.com> * cvm tests fix Signed-off-by: Sammy Oina <sammyoina@gmail.com> * fix test Signed-off-by: Sammy Oina <sammyoina@gmail.com> * add cli and test Signed-off-by: Sammy Oina <sammyoina@gmail.com> * restore result cli Signed-off-by: Sammy Oina <sammyoina@gmail.com> * fix tests Signed-off-by: Sammy Oina <sammyoina@gmail.com> * pass certs and env Signed-off-by: Sammy Oina <sammyoina@gmail.com> * update go Signed-off-by: Sammy Oina <sammyoina@gmail.com> * downgrade Signed-off-by: Sammy Oina <sammyoina@gmail.com> * downgrade again Signed-off-by: Sammy Oina <sammyoina@gmail.com> * simplify Signed-off-by: Sammy Oina <sammyoina@gmail.com> * simplify Signed-off-by: Sammy Oina <sammyoina@gmail.com> * configure cvms Signed-off-by: Sammy Oina <sammyoina@gmail.com> * remove unused gRPC API files and server implementation Signed-off-by: Sammy Oina <sammyoina@gmail.com> * refactor: use constants for CLI command flags and environment variables Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
This commit is contained in:
committed by
GitHub
parent
1f32f516b0
commit
881aaaab0f
+70
-8
@@ -3,31 +3,54 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/ultravioletrs/cocos/manager"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
const (
|
||||
serverURL = "server-url"
|
||||
serverCA = "server-ca"
|
||||
clientKey = "client-key"
|
||||
clientCrt = "client-crt"
|
||||
logLevel = "log-level"
|
||||
)
|
||||
|
||||
var (
|
||||
agentCVMServerUrl string
|
||||
agentCVMServerCA string
|
||||
agentCVMClientKey string
|
||||
agentCVMClientCrt string
|
||||
agentLogLevel string
|
||||
)
|
||||
|
||||
func (c *CLI) NewCreateVMCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
cmd := &cobra.Command{
|
||||
Use: "create-vm",
|
||||
Short: "Create a new virtual machine",
|
||||
Example: `create-vm`,
|
||||
Args: cobra.ExactArgs(0),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := c.InitializeManagerClient(cmd); err == nil {
|
||||
defer c.Close()
|
||||
}
|
||||
|
||||
if c.connectErr != nil {
|
||||
if err := c.InitializeManagerClient(cmd); err != nil {
|
||||
printError(cmd, "Failed to connect to manager: %v ❌ ", c.connectErr)
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
createReq, err := loadCerts()
|
||||
if err != nil {
|
||||
printError(cmd, "Error loading certs: %v ❌ ", err)
|
||||
return
|
||||
}
|
||||
|
||||
createReq.AgentCvmServerUrl = agentCVMServerUrl
|
||||
createReq.AgentLogLevel = agentLogLevel
|
||||
|
||||
cmd.Println("🔗 Creating a new virtual machine")
|
||||
|
||||
res, err := c.managerClient.CreateVm(cmd.Context(), &emptypb.Empty{})
|
||||
res, err := c.managerClient.CreateVm(cmd.Context(), createReq)
|
||||
if err != nil {
|
||||
printError(cmd, "Error creating virtual machine: %v ❌ ", err)
|
||||
return
|
||||
@@ -36,6 +59,14 @@ func (c *CLI) NewCreateVMCmd() *cobra.Command {
|
||||
cmd.Println(color.New(color.FgGreen).Sprintf("✅ Virtual machine created successfully with id %s and port %s", res.SvmId, res.ForwardedPort))
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&agentCVMServerUrl, serverURL, "", "CVM server URL")
|
||||
cmd.Flags().StringVar(&agentCVMServerCA, serverCA, "", "CVM server CA")
|
||||
cmd.Flags().StringVar(&agentCVMClientKey, clientKey, "", "CVM client key")
|
||||
cmd.Flags().StringVar(&agentCVMClientCrt, clientCrt, "", "CVM client crt")
|
||||
cmd.Flags().StringVar(&agentLogLevel, logLevel, "", "Agent Log level")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *CLI) NewRemoveVMCmd() *cobra.Command {
|
||||
@@ -66,3 +97,34 @@ func (c *CLI) NewRemoveVMCmd() *cobra.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func fileReader(path string) ([]byte, error) {
|
||||
if path == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return os.ReadFile(path)
|
||||
}
|
||||
|
||||
func loadCerts() (*manager.CreateReq, error) {
|
||||
clientKey, err := fileReader(agentCVMClientKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clientCrt, err := fileReader(agentCVMClientCrt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serverCA, err := fileReader(agentCVMServerCA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &manager.CreateReq{
|
||||
AgentCvmServerCaCert: serverCA,
|
||||
AgentCvmClientKey: clientKey,
|
||||
AgentCvmClientCert: clientCrt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -65,3 +65,9 @@ CONFIG_PREEMPT_DYNAMIC=n
|
||||
CONFIG_DEBUG_PREEMPT=n
|
||||
CONFIG_CGROUP_MISC=y
|
||||
CONFIG_X86_CPUID=y
|
||||
|
||||
CONFIG_NET_9P=y
|
||||
CONFIG_NET_9P_VIRTIO=y
|
||||
CONFIG_9P_FS=y
|
||||
CONFIG_9P_FS_POSIX_ACL=y
|
||||
CONFIG_9P_FS_SECURITY=y
|
||||
|
||||
@@ -6,6 +6,23 @@ set -e
|
||||
# Add a console on tty1
|
||||
if [ -e ${TARGET_DIR}/etc/inittab ]; then
|
||||
grep -qE '^tty1::' ${TARGET_DIR}/etc/inittab || \
|
||||
sed -i '/GENERIC_SERIAL/a\
|
||||
sed -i '/GENERIC_SERIAL/a\
|
||||
tty1::respawn:/sbin/getty -L tty1 0 vt100 # QEMU graphical window' ${TARGET_DIR}/etc/inittab
|
||||
fi
|
||||
|
||||
# Create the mount points
|
||||
# Create the mount points
|
||||
mkdir -p ${TARGET_DIR}/etc/certs
|
||||
mkdir -p ${TARGET_DIR}/etc/cocos
|
||||
|
||||
# Ensure /etc/fstab exists
|
||||
if [ ! -f "${TARGET_DIR}/etc/fstab" ]; then
|
||||
touch "${TARGET_DIR}/etc/fstab"
|
||||
fi
|
||||
|
||||
# Add the 9p entries to /etc/fstab
|
||||
grep -q "certs_share /etc/certs" ${TARGET_DIR}/etc/fstab || \
|
||||
echo "certs_share /etc/certs 9p trans=virtio,version=9p2000.L,cache=mmap 0 0" >> "${TARGET_DIR}/etc/fstab"
|
||||
|
||||
grep -q "env_share /etc/cocos" ${TARGET_DIR}/etc/fstab || \
|
||||
echo "env_share /etc/cocos 9p trans=virtio,version=9p2000.L,cache=mmap 0 0" >> "${TARGET_DIR}/etc/fstab"
|
||||
|
||||
@@ -14,6 +14,8 @@ BR2_SYSTEM_BIN_SH_BASH=y
|
||||
BR2_TARGET_ROOTFS_CPIO=y
|
||||
BR2_TARGET_ROOTFS_CPIO_FULL=y
|
||||
BR2_TARGET_ROOTFS_CPIO_GZIP=y
|
||||
BR2_TARGET_ROOTFS_OVERLAY="overlay"
|
||||
BR2_PACKAGE_9PFS=y
|
||||
|
||||
# Image
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_COCOS_PATH)/board/cocos/post-build.sh"
|
||||
|
||||
@@ -8,8 +8,7 @@ WorkingDirectory=/cocos
|
||||
StandardOutput=file:/var/log/cocos/agent.stdout
|
||||
StandardError=file:/var/log/cocos/agent.stderr
|
||||
|
||||
Environment=AGENT_GRPC_PORT=7002
|
||||
Environment=AGENT_LOG_LEVEL=info
|
||||
EnvironmentFile=/etc/cocos/environment
|
||||
|
||||
ExecStartPre=/cocos_init/agent_setup.sh
|
||||
ExecStart=/cocos_init/agent_start_script.sh
|
||||
|
||||
@@ -27,8 +27,8 @@ func NewServer(svc manager.Service) manager.ManagerServiceServer {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *grpcServer) CreateVm(ctx context.Context, _ *emptypb.Empty) (*manager.CreateRes, error) {
|
||||
port, id, err := s.svc.CreateVM(ctx)
|
||||
func (s *grpcServer) CreateVm(ctx context.Context, req *manager.CreateReq) (*manager.CreateRes, error) {
|
||||
port, id, err := s.svc.CreateVM(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func LoggingMiddleware(svc manager.Service, logger *slog.Logger) manager.Service
|
||||
return &loggingMiddleware{logger, svc}
|
||||
}
|
||||
|
||||
func (lm *loggingMiddleware) CreateVM(ctx context.Context) (agentAddr string, id string, err error) {
|
||||
func (lm *loggingMiddleware) CreateVM(ctx context.Context, req *manager.CreateReq) (agentAddr string, id string, err error) {
|
||||
defer func(begin time.Time) {
|
||||
message := fmt.Sprintf("Method CreateVM for id %s on port %s took %s to complete", id, agentAddr, time.Since(begin))
|
||||
if err != nil {
|
||||
@@ -37,7 +37,7 @@ func (lm *loggingMiddleware) CreateVM(ctx context.Context) (agentAddr string, id
|
||||
lm.logger.Info(message)
|
||||
}(time.Now())
|
||||
|
||||
return lm.svc.CreateVM(ctx)
|
||||
return lm.svc.CreateVM(ctx, req)
|
||||
}
|
||||
|
||||
func (lm *loggingMiddleware) RemoveVM(ctx context.Context, id string) (err error) {
|
||||
|
||||
@@ -32,13 +32,13 @@ func MetricsMiddleware(svc manager.Service, counter metrics.Counter, latency met
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *metricsMiddleware) CreateVM(ctx context.Context) (string, string, error) {
|
||||
func (ms *metricsMiddleware) CreateVM(ctx context.Context, req *manager.CreateReq) (string, string, error) {
|
||||
defer func(begin time.Time) {
|
||||
ms.counter.With("method", "Run").Add(1)
|
||||
ms.latency.With("method", "Run").Observe(time.Since(begin).Seconds())
|
||||
}(time.Now())
|
||||
|
||||
return ms.svc.CreateVM(ctx)
|
||||
return ms.svc.CreateVM(ctx, req)
|
||||
}
|
||||
|
||||
func (ms *metricsMiddleware) RemoveVM(ctx context.Context, computationID string) error {
|
||||
|
||||
+173
-80
@@ -24,6 +24,82 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type CreateReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AgentLogLevel string `protobuf:"bytes,1,opt,name=agent_log_level,json=agentLogLevel,proto3" json:"agent_log_level,omitempty"`
|
||||
AgentCvmServerCaCert []byte `protobuf:"bytes,2,opt,name=agent_cvm_server_ca_cert,json=agentCvmServerCaCert,proto3" json:"agent_cvm_server_ca_cert,omitempty"`
|
||||
AgentCvmClientKey []byte `protobuf:"bytes,3,opt,name=agent_cvm_client_key,json=agentCvmClientKey,proto3" json:"agent_cvm_client_key,omitempty"`
|
||||
AgentCvmClientCert []byte `protobuf:"bytes,4,opt,name=agent_cvm_client_cert,json=agentCvmClientCert,proto3" json:"agent_cvm_client_cert,omitempty"`
|
||||
AgentCvmServerUrl string `protobuf:"bytes,5,opt,name=agent_cvm_server_url,json=agentCvmServerUrl,proto3" json:"agent_cvm_server_url,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreateReq) Reset() {
|
||||
*x = CreateReq{}
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CreateReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreateReq) ProtoMessage() {}
|
||||
|
||||
func (x *CreateReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CreateReq.ProtoReflect.Descriptor instead.
|
||||
func (*CreateReq) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *CreateReq) GetAgentLogLevel() string {
|
||||
if x != nil {
|
||||
return x.AgentLogLevel
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *CreateReq) GetAgentCvmServerCaCert() []byte {
|
||||
if x != nil {
|
||||
return x.AgentCvmServerCaCert
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *CreateReq) GetAgentCvmClientKey() []byte {
|
||||
if x != nil {
|
||||
return x.AgentCvmClientKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *CreateReq) GetAgentCvmClientCert() []byte {
|
||||
if x != nil {
|
||||
return x.AgentCvmClientCert
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *CreateReq) GetAgentCvmServerUrl() string {
|
||||
if x != nil {
|
||||
return x.AgentCvmServerUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type CreateRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ForwardedPort string `protobuf:"bytes,1,opt,name=forwarded_port,json=forwardedPort,proto3" json:"forwarded_port,omitempty"`
|
||||
@@ -34,7 +110,7 @@ type CreateRes struct {
|
||||
|
||||
func (x *CreateRes) Reset() {
|
||||
*x = CreateRes{}
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -46,7 +122,7 @@ func (x *CreateRes) String() string {
|
||||
func (*CreateRes) ProtoMessage() {}
|
||||
|
||||
func (x *CreateRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[0]
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -59,7 +135,7 @@ func (x *CreateRes) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use CreateRes.ProtoReflect.Descriptor instead.
|
||||
func (*CreateRes) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{0}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *CreateRes) GetForwardedPort() string {
|
||||
@@ -85,7 +161,7 @@ type RemoveReq struct {
|
||||
|
||||
func (x *RemoveReq) Reset() {
|
||||
*x = RemoveReq{}
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -97,7 +173,7 @@ func (x *RemoveReq) String() string {
|
||||
func (*RemoveReq) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[1]
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -110,7 +186,7 @@ func (x *RemoveReq) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RemoveReq.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveReq) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{1}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *RemoveReq) GetSvmId() string {
|
||||
@@ -130,7 +206,7 @@ type AttestationPolicyRes struct {
|
||||
|
||||
func (x *AttestationPolicyRes) Reset() {
|
||||
*x = AttestationPolicyRes{}
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -142,7 +218,7 @@ func (x *AttestationPolicyRes) String() string {
|
||||
func (*AttestationPolicyRes) ProtoMessage() {}
|
||||
|
||||
func (x *AttestationPolicyRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[2]
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -155,7 +231,7 @@ func (x *AttestationPolicyRes) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AttestationPolicyRes.ProtoReflect.Descriptor instead.
|
||||
func (*AttestationPolicyRes) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{2}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *AttestationPolicyRes) GetInfo() []byte {
|
||||
@@ -186,7 +262,7 @@ type SVMInfoRes struct {
|
||||
|
||||
func (x *SVMInfoRes) Reset() {
|
||||
*x = SVMInfoRes{}
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -198,7 +274,7 @@ func (x *SVMInfoRes) String() string {
|
||||
func (*SVMInfoRes) ProtoMessage() {}
|
||||
|
||||
func (x *SVMInfoRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[3]
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -211,7 +287,7 @@ func (x *SVMInfoRes) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use SVMInfoRes.ProtoReflect.Descriptor instead.
|
||||
func (*SVMInfoRes) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{3}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *SVMInfoRes) GetId() string {
|
||||
@@ -265,7 +341,7 @@ type AttestationPolicyReq struct {
|
||||
|
||||
func (x *AttestationPolicyReq) Reset() {
|
||||
*x = AttestationPolicyReq{}
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -277,7 +353,7 @@ func (x *AttestationPolicyReq) String() string {
|
||||
func (*AttestationPolicyReq) ProtoMessage() {}
|
||||
|
||||
func (x *AttestationPolicyReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[4]
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -290,7 +366,7 @@ func (x *AttestationPolicyReq) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AttestationPolicyReq.ProtoReflect.Descriptor instead.
|
||||
func (*AttestationPolicyReq) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{4}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *AttestationPolicyReq) GetId() string {
|
||||
@@ -309,7 +385,7 @@ type SVMInfoReq struct {
|
||||
|
||||
func (x *SVMInfoReq) Reset() {
|
||||
*x = SVMInfoReq{}
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
mi := &file_manager_manager_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -321,7 +397,7 @@ func (x *SVMInfoReq) String() string {
|
||||
func (*SVMInfoReq) ProtoMessage() {}
|
||||
|
||||
func (x *SVMInfoReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_manager_manager_proto_msgTypes[5]
|
||||
mi := &file_manager_manager_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -334,7 +410,7 @@ func (x *SVMInfoReq) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use SVMInfoReq.ProtoReflect.Descriptor instead.
|
||||
func (*SVMInfoReq) Descriptor() ([]byte, []int) {
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{5}
|
||||
return file_manager_manager_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *SVMInfoReq) GetId() string {
|
||||
@@ -350,52 +426,68 @@ var file_manager_manager_proto_rawDesc = []byte{
|
||||
0x0a, 0x15, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||
0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||
0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x49, 0x0a,
|
||||
0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x6f,
|
||||
0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0d, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x50, 0x6f, 0x72,
|
||||
0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x76, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x73, 0x76, 0x6d, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x09, 0x52, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x76, 0x6d, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x76, 0x6d, 0x49, 0x64, 0x22, 0x3a, 0x0a, 0x14,
|
||||
0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63,
|
||||
0x79, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x0a, 0x53, 0x56, 0x4d,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x76, 0x6d, 0x66, 0x5f,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f,
|
||||
0x76, 0x6d, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x70,
|
||||
0x75, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x70, 0x75,
|
||||
0x4e, 0x75, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x70, 0x75, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6d, 0x64, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x43, 0x6d, 0x64, 0x12, 0x1f, 0x0a,
|
||||
0x0b, 0x65, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x65, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x26,
|
||||
0x0a, 0x14, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1c, 0x0a, 0x0a, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x69, 0x64, 0x32, 0x90, 0x02, 0x0a, 0x0e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x56, 0x6d, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x6d, 0x61,
|
||||
0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x22,
|
||||
0x00, 0x12, 0x38, 0x0a, 0x08, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6d, 0x12, 0x12, 0x2e,
|
||||
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65,
|
||||
0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x07, 0x53,
|
||||
0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x13, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||
0x2e, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x6d, 0x61,
|
||||
0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73,
|
||||
0x22, 0x00, 0x12, 0x53, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||
0x72, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||
0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x80, 0x02,
|
||||
0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x26, 0x0a, 0x0f, 0x61,
|
||||
0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65,
|
||||
0x76, 0x65, 0x6c, 0x12, 0x36, 0x0a, 0x18, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x76, 0x6d,
|
||||
0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x14, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x76, 0x6d, 0x53,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x43, 0x65, 0x72, 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x61,
|
||||
0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74,
|
||||
0x43, 0x76, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x15,
|
||||
0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
||||
0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x61, 0x67, 0x65,
|
||||
0x6e, 0x74, 0x43, 0x76, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x12,
|
||||
0x2f, 0x0a, 0x14, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x76, 0x6d, 0x5f, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x61,
|
||||
0x67, 0x65, 0x6e, 0x74, 0x43, 0x76, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x72, 0x6c,
|
||||
0x22, 0x49, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x25, 0x0a,
|
||||
0x0e, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64,
|
||||
0x50, 0x6f, 0x72, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x76, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x76, 0x6d, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x09, 0x52,
|
||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x76, 0x6d, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x76, 0x6d, 0x49, 0x64, 0x22,
|
||||
0x3a, 0x0a, 0x14, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f,
|
||||
0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x0a,
|
||||
0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x76,
|
||||
0x6d, 0x66, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0b, 0x6f, 0x76, 0x6d, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a,
|
||||
0x07, 0x63, 0x70, 0x75, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06,
|
||||
0x63, 0x70, 0x75, 0x4e, 0x75, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x70, 0x75, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x6d, 0x64, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x43, 0x6d, 0x64,
|
||||
0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x22, 0x26, 0x0a, 0x14, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1c, 0x0a, 0x0a, 0x53, 0x56, 0x4d,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x32, 0x8c, 0x02, 0x0a, 0x0e, 0x4d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x56, 0x6d, 0x12, 0x12, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x22, 0x00,
|
||||
0x12, 0x38, 0x0a, 0x08, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6d, 0x12, 0x12, 0x2e, 0x6d,
|
||||
0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71,
|
||||
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x07, 0x53, 0x56,
|
||||
0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x13, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e,
|
||||
0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x56, 0x4d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x22,
|
||||
0x00, 0x12, 0x53, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||
0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69,
|
||||
0x63, 0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x63, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e,
|
||||
0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63,
|
||||
0x79, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -410,25 +502,26 @@ func file_manager_manager_proto_rawDescGZIP() []byte {
|
||||
return file_manager_manager_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_manager_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_manager_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_manager_manager_proto_goTypes = []any{
|
||||
(*CreateRes)(nil), // 0: manager.CreateRes
|
||||
(*RemoveReq)(nil), // 1: manager.RemoveReq
|
||||
(*AttestationPolicyRes)(nil), // 2: manager.AttestationPolicyRes
|
||||
(*SVMInfoRes)(nil), // 3: manager.SVMInfoRes
|
||||
(*AttestationPolicyReq)(nil), // 4: manager.AttestationPolicyReq
|
||||
(*SVMInfoReq)(nil), // 5: manager.SVMInfoReq
|
||||
(*emptypb.Empty)(nil), // 6: google.protobuf.Empty
|
||||
(*CreateReq)(nil), // 0: manager.CreateReq
|
||||
(*CreateRes)(nil), // 1: manager.CreateRes
|
||||
(*RemoveReq)(nil), // 2: manager.RemoveReq
|
||||
(*AttestationPolicyRes)(nil), // 3: manager.AttestationPolicyRes
|
||||
(*SVMInfoRes)(nil), // 4: manager.SVMInfoRes
|
||||
(*AttestationPolicyReq)(nil), // 5: manager.AttestationPolicyReq
|
||||
(*SVMInfoReq)(nil), // 6: manager.SVMInfoReq
|
||||
(*emptypb.Empty)(nil), // 7: google.protobuf.Empty
|
||||
}
|
||||
var file_manager_manager_proto_depIdxs = []int32{
|
||||
6, // 0: manager.ManagerService.CreateVm:input_type -> google.protobuf.Empty
|
||||
1, // 1: manager.ManagerService.RemoveVm:input_type -> manager.RemoveReq
|
||||
5, // 2: manager.ManagerService.SVMInfo:input_type -> manager.SVMInfoReq
|
||||
4, // 3: manager.ManagerService.AttestationPolicy:input_type -> manager.AttestationPolicyReq
|
||||
0, // 4: manager.ManagerService.CreateVm:output_type -> manager.CreateRes
|
||||
6, // 5: manager.ManagerService.RemoveVm:output_type -> google.protobuf.Empty
|
||||
3, // 6: manager.ManagerService.SVMInfo:output_type -> manager.SVMInfoRes
|
||||
2, // 7: manager.ManagerService.AttestationPolicy:output_type -> manager.AttestationPolicyRes
|
||||
0, // 0: manager.ManagerService.CreateVm:input_type -> manager.CreateReq
|
||||
2, // 1: manager.ManagerService.RemoveVm:input_type -> manager.RemoveReq
|
||||
6, // 2: manager.ManagerService.SVMInfo:input_type -> manager.SVMInfoReq
|
||||
5, // 3: manager.ManagerService.AttestationPolicy:input_type -> manager.AttestationPolicyReq
|
||||
1, // 4: manager.ManagerService.CreateVm:output_type -> manager.CreateRes
|
||||
7, // 5: manager.ManagerService.RemoveVm:output_type -> google.protobuf.Empty
|
||||
4, // 6: manager.ManagerService.SVMInfo:output_type -> manager.SVMInfoRes
|
||||
3, // 7: manager.ManagerService.AttestationPolicy:output_type -> manager.AttestationPolicyRes
|
||||
4, // [4:8] is the sub-list for method output_type
|
||||
0, // [0:4] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
@@ -447,7 +540,7 @@ func file_manager_manager_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_manager_manager_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -10,12 +10,20 @@ package manager;
|
||||
option go_package = "./manager";
|
||||
|
||||
service ManagerService {
|
||||
rpc CreateVm(google.protobuf.Empty) returns (CreateRes) {}
|
||||
rpc CreateVm(CreateReq) returns (CreateRes) {}
|
||||
rpc RemoveVm(RemoveReq) returns (google.protobuf.Empty) {}
|
||||
rpc SVMInfo(SVMInfoReq) returns (SVMInfoRes) {}
|
||||
rpc AttestationPolicy(AttestationPolicyReq) returns (AttestationPolicyRes) {}
|
||||
}
|
||||
|
||||
message CreateReq{
|
||||
string agent_log_level = 1;
|
||||
bytes agent_cvm_server_ca_cert = 2;
|
||||
bytes agent_cvm_client_key = 3;
|
||||
bytes agent_cvm_client_cert = 4;
|
||||
string agent_cvm_server_url = 5;
|
||||
}
|
||||
|
||||
message CreateRes{
|
||||
string forwarded_port = 1;
|
||||
string svm_id = 2;
|
||||
|
||||
@@ -33,7 +33,7 @@ const (
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type ManagerServiceClient interface {
|
||||
CreateVm(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateRes, error)
|
||||
CreateVm(ctx context.Context, in *CreateReq, opts ...grpc.CallOption) (*CreateRes, error)
|
||||
RemoveVm(ctx context.Context, in *RemoveReq, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
SVMInfo(ctx context.Context, in *SVMInfoReq, opts ...grpc.CallOption) (*SVMInfoRes, error)
|
||||
AttestationPolicy(ctx context.Context, in *AttestationPolicyReq, opts ...grpc.CallOption) (*AttestationPolicyRes, error)
|
||||
@@ -47,7 +47,7 @@ func NewManagerServiceClient(cc grpc.ClientConnInterface) ManagerServiceClient {
|
||||
return &managerServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *managerServiceClient) CreateVm(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateRes, error) {
|
||||
func (c *managerServiceClient) CreateVm(ctx context.Context, in *CreateReq, opts ...grpc.CallOption) (*CreateRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(CreateRes)
|
||||
err := c.cc.Invoke(ctx, ManagerService_CreateVm_FullMethodName, in, out, cOpts...)
|
||||
@@ -91,7 +91,7 @@ func (c *managerServiceClient) AttestationPolicy(ctx context.Context, in *Attest
|
||||
// All implementations must embed UnimplementedManagerServiceServer
|
||||
// for forward compatibility.
|
||||
type ManagerServiceServer interface {
|
||||
CreateVm(context.Context, *emptypb.Empty) (*CreateRes, error)
|
||||
CreateVm(context.Context, *CreateReq) (*CreateRes, error)
|
||||
RemoveVm(context.Context, *RemoveReq) (*emptypb.Empty, error)
|
||||
SVMInfo(context.Context, *SVMInfoReq) (*SVMInfoRes, error)
|
||||
AttestationPolicy(context.Context, *AttestationPolicyReq) (*AttestationPolicyRes, error)
|
||||
@@ -105,7 +105,7 @@ type ManagerServiceServer interface {
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedManagerServiceServer struct{}
|
||||
|
||||
func (UnimplementedManagerServiceServer) CreateVm(context.Context, *emptypb.Empty) (*CreateRes, error) {
|
||||
func (UnimplementedManagerServiceServer) CreateVm(context.Context, *CreateReq) (*CreateRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateVm not implemented")
|
||||
}
|
||||
func (UnimplementedManagerServiceServer) RemoveVm(context.Context, *RemoveReq) (*emptypb.Empty, error) {
|
||||
@@ -139,7 +139,7 @@ func RegisterManagerServiceServer(s grpc.ServiceRegistrar, srv ManagerServiceSer
|
||||
}
|
||||
|
||||
func _ManagerService_CreateVm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(emptypb.Empty)
|
||||
in := new(CreateReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func _ManagerService_CreateVm_Handler(srv interface{}, ctx context.Context, dec
|
||||
FullMethod: ManagerService_CreateVm_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ManagerServiceServer).CreateVm(ctx, req.(*emptypb.Empty))
|
||||
return srv.(ManagerServiceServer).CreateVm(ctx, req.(*CreateReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
+18
-16
@@ -9,6 +9,7 @@ import (
|
||||
context "context"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
manager "github.com/ultravioletrs/cocos/manager"
|
||||
)
|
||||
|
||||
// Service is an autogenerated mock type for the Service type
|
||||
@@ -24,9 +25,9 @@ func (_m *Service) EXPECT() *Service_Expecter {
|
||||
return &Service_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// CreateVM provides a mock function with given fields: ctx
|
||||
func (_m *Service) CreateVM(ctx context.Context) (string, string, error) {
|
||||
ret := _m.Called(ctx)
|
||||
// CreateVM provides a mock function with given fields: ctx, req
|
||||
func (_m *Service) CreateVM(ctx context.Context, req *manager.CreateReq) (string, string, error) {
|
||||
ret := _m.Called(ctx, req)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CreateVM")
|
||||
@@ -35,23 +36,23 @@ func (_m *Service) CreateVM(ctx context.Context) (string, string, error) {
|
||||
var r0 string
|
||||
var r1 string
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context) (string, string, error)); ok {
|
||||
return rf(ctx)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *manager.CreateReq) (string, string, error)); ok {
|
||||
return rf(ctx, req)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context) string); ok {
|
||||
r0 = rf(ctx)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *manager.CreateReq) string); ok {
|
||||
r0 = rf(ctx, req)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context) string); ok {
|
||||
r1 = rf(ctx)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *manager.CreateReq) string); ok {
|
||||
r1 = rf(ctx, req)
|
||||
} else {
|
||||
r1 = ret.Get(1).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func(context.Context) error); ok {
|
||||
r2 = rf(ctx)
|
||||
if rf, ok := ret.Get(2).(func(context.Context, *manager.CreateReq) error); ok {
|
||||
r2 = rf(ctx, req)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
@@ -66,13 +67,14 @@ type Service_CreateVM_Call struct {
|
||||
|
||||
// CreateVM is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
func (_e *Service_Expecter) CreateVM(ctx interface{}) *Service_CreateVM_Call {
|
||||
return &Service_CreateVM_Call{Call: _e.mock.On("CreateVM", ctx)}
|
||||
// - req *manager.CreateReq
|
||||
func (_e *Service_Expecter) CreateVM(ctx interface{}, req interface{}) *Service_CreateVM_Call {
|
||||
return &Service_CreateVM_Call{Call: _e.mock.On("CreateVM", ctx, req)}
|
||||
}
|
||||
|
||||
func (_c *Service_CreateVM_Call) Run(run func(ctx context.Context)) *Service_CreateVM_Call {
|
||||
func (_c *Service_CreateVM_Call) Run(run func(ctx context.Context, req *manager.CreateReq)) *Service_CreateVM_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context))
|
||||
run(args[0].(context.Context), args[1].(*manager.CreateReq))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
@@ -82,7 +84,7 @@ func (_c *Service_CreateVM_Call) Return(_a0 string, _a1 string, _a2 error) *Serv
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *Service_CreateVM_Call) RunAndReturn(run func(context.Context) (string, string, error)) *Service_CreateVM_Call {
|
||||
func (_c *Service_CreateVM_Call) RunAndReturn(run func(context.Context, *manager.CreateReq) (string, string, error)) *Service_CreateVM_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
@@ -106,6 +106,10 @@ type Config struct {
|
||||
|
||||
// ports
|
||||
HostFwdRange string `env:"HOST_FWD_RANGE" envDefault:"6100-6200"`
|
||||
|
||||
// mounts
|
||||
CertsMount string `env:"CERTS_MOUNT" envDefault:""`
|
||||
EnvMount string `env:"ENV_MOUNT" envDefault:""`
|
||||
}
|
||||
|
||||
func (config Config) ConstructQemuArgs() []string {
|
||||
@@ -216,5 +220,15 @@ func (config Config) ConstructQemuArgs() []string {
|
||||
|
||||
args = append(args, "-monitor", config.Monitor)
|
||||
|
||||
if config.CertsMount != "" {
|
||||
args = append(args, "-fsdev", fmt.Sprintf("local,id=cert_fs,path=%s,security_model=mapped", config.CertsMount))
|
||||
args = append(args, "-device", "virtio-9p-pci,fsdev=cert_fs,mount_tag=certs_share")
|
||||
}
|
||||
|
||||
if config.EnvMount != "" {
|
||||
args = append(args, "-fsdev", fmt.Sprintf("local,id=env_fs,path=%s,security_model=mapped", config.EnvMount))
|
||||
args = append(args, "-device", "virtio-9p-pci,fsdev=env_fs,mount_tag=env_share")
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
@@ -94,6 +94,18 @@ func (v *qemuVM) Stop() error {
|
||||
return fmt.Errorf("failed to send SIGTERM: %v", err)
|
||||
}
|
||||
|
||||
if v.vmi.Config.CertsMount != "" {
|
||||
if err := os.RemoveAll(v.vmi.Config.CertsMount); err != nil {
|
||||
return fmt.Errorf("failed to remove certs mount: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if v.vmi.Config.EnvMount != "" {
|
||||
if err := os.RemoveAll(v.vmi.Config.EnvMount); err != nil {
|
||||
return fmt.Errorf("failed to remove env mount: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
_, err := v.cmd.Process.Wait()
|
||||
|
||||
+86
-4
@@ -26,8 +26,17 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
hashLength = 32
|
||||
persistenceDir = "/tmp/cocos"
|
||||
hashLength = 32
|
||||
persistenceDir = "/tmp/cocos"
|
||||
agentLogLevelKey = "AGENT_LOG_LEVEL"
|
||||
agentCvmGrpcUrlKey = "AGENT_CVM_GRPC_URL"
|
||||
agentCvmClientCertKey = "AGENT_CVM_CLIENT_CERT"
|
||||
agentCvmClientKey = "AGENT_CVM_CLIENT_KEY"
|
||||
agentCvmServerCaCertKey = "AGENT_CVM_SERVER_CA_CERT"
|
||||
defClientCertPath = "/etc/certs/cert.pem"
|
||||
defClientKeyPath = "/etc/certs/key.pem"
|
||||
defServerCaCertPath = "/etc/certs/ca.pem"
|
||||
cvmEnvironmentFile = "environment"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -62,7 +71,7 @@ var (
|
||||
// implementation, and all of its decorators (e.g. logging & metrics).
|
||||
type Service interface {
|
||||
// Run create a computation.
|
||||
CreateVM(ctx context.Context) (string, string, error)
|
||||
CreateVM(ctx context.Context, req *CreateReq) (string, string, error)
|
||||
// Stop stops a computation.
|
||||
RemoveVM(ctx context.Context, computationID string) error
|
||||
// FetchAttestationPolicy measures and fetches the attestation policy.
|
||||
@@ -118,7 +127,7 @@ func New(cfg qemu.Config, attestationPolicyBinPath string, logger *slog.Logger,
|
||||
return ms, nil
|
||||
}
|
||||
|
||||
func (ms *managerService) CreateVM(ctx context.Context) (string, string, error) {
|
||||
func (ms *managerService) CreateVM(ctx context.Context, req *CreateReq) (string, string, error) {
|
||||
id := uuid.New().String()
|
||||
ms.mu.Lock()
|
||||
cfg := qemu.VMInfo{
|
||||
@@ -127,6 +136,19 @@ func (ms *managerService) CreateVM(ctx context.Context) (string, string, error)
|
||||
}
|
||||
ms.mu.Unlock()
|
||||
|
||||
tmpCertsDir, err := tempCertMount(id, req)
|
||||
if err != nil {
|
||||
return "", id, err
|
||||
}
|
||||
|
||||
tmpEnvDir, err := tmpEnvironment(id, req)
|
||||
if err != nil {
|
||||
return "", id, err
|
||||
}
|
||||
|
||||
cfg.Config.CertsMount = tmpCertsDir
|
||||
cfg.Config.EnvMount = tmpEnvDir
|
||||
|
||||
if ms.qemuCfg.EnableSEVSNP || ms.qemuCfg.EnableSEV {
|
||||
cmd := exec.Command("sudo", fmt.Sprintf("%s/attestation_policy", ms.attestationPolicyBinaryPath), "--policy", "196608")
|
||||
|
||||
@@ -349,3 +371,63 @@ func (ms *managerService) processExists(pid int) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func tempCertMount(id string, req *CreateReq) (string, error) {
|
||||
dir, err := os.MkdirTemp("/tmp", id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err = os.WriteFile(fmt.Sprintf("%s/%s", dir, "cert.pem"), req.AgentCvmClientCert, 0o644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err = os.WriteFile(fmt.Sprintf("%s/%s", dir, "key.pem"), req.AgentCvmClientKey, 0o644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err = os.WriteFile(fmt.Sprintf("%s/%s", dir, "ca.pem"), req.AgentCvmServerCaCert, 0o644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
func tmpEnvironment(id string, req *CreateReq) (string, error) {
|
||||
dir, err := os.MkdirTemp("/tmp", id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
envMap := map[string]string{
|
||||
agentLogLevelKey: req.AgentLogLevel,
|
||||
agentCvmGrpcUrlKey: req.AgentCvmServerUrl,
|
||||
}
|
||||
|
||||
if req.AgentCvmClientCert != nil {
|
||||
envMap[agentCvmClientCertKey] = defClientCertPath
|
||||
}
|
||||
if req.AgentCvmClientKey != nil {
|
||||
envMap[agentCvmClientKey] = defClientKeyPath
|
||||
}
|
||||
if req.AgentCvmServerCaCert != nil {
|
||||
envMap[agentCvmServerCaCertKey] = defServerCaCertPath
|
||||
}
|
||||
|
||||
envFile, err := os.OpenFile(fmt.Sprintf("%s/%s", dir, cvmEnvironmentFile), os.O_CREATE|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for k, v := range envMap {
|
||||
if _, err = envFile.WriteString(fmt.Sprintf("%s=%s\n", k, v)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if err = envFile.Close(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ func TestRun(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
port, _, err := ms.CreateVM(ctx)
|
||||
port, _, err := ms.CreateVM(ctx, &CreateReq{})
|
||||
|
||||
if tt.expectedError != nil {
|
||||
assert.Error(t, err)
|
||||
|
||||
@@ -21,11 +21,11 @@ func New(svc manager.Service, tracer trace.Tracer) manager.Service {
|
||||
return &tracingMiddleware{tracer, svc}
|
||||
}
|
||||
|
||||
func (tm *tracingMiddleware) CreateVM(ctx context.Context) (string, string, error) {
|
||||
func (tm *tracingMiddleware) CreateVM(ctx context.Context, req *manager.CreateReq) (string, string, error) {
|
||||
ctx, span := tm.tracer.Start(ctx, "run")
|
||||
defer span.End()
|
||||
|
||||
return tm.svc.CreateVM(ctx)
|
||||
return tm.svc.CreateVM(ctx, req)
|
||||
}
|
||||
|
||||
func (tm *tracingMiddleware) RemoveVM(ctx context.Context, id string) error {
|
||||
|
||||
@@ -84,7 +84,6 @@ func (s *svc) Run(ctx context.Context, ipAddress string, sendMessage cvmgrpc.Sen
|
||||
ResultConsumers: []*cvms.ResultConsumer{{UserKey: pubPem.Bytes}},
|
||||
AgentConfig: &cvms.AgentConfig{
|
||||
Port: "7002",
|
||||
LogLevel: "debug",
|
||||
AttestedTls: attestedTLS,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user