mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-08-07 07:14:50 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 747aaaa5eb | |||
| 87f2728cc4 | |||
| 22c14cb438 |
@@ -34,7 +34,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up protoc
|
- name: Set up protoc
|
||||||
run: |
|
run: |
|
||||||
PROTOC_VERSION=35.0
|
PROTOC_VERSION=35.1
|
||||||
PROTOC_GEN_VERSION=v1.36.11
|
PROTOC_GEN_VERSION=v1.36.11
|
||||||
PROTOC_GRPC_VERSION=v1.6.0
|
PROTOC_GRPC_VERSION=v1.6.0
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: agent/agent.proto
|
// source: agent/agent.proto
|
||||||
|
|
||||||
package agent
|
package agent
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v7.35.0
|
// - protoc v7.35.1
|
||||||
// source: agent/agent.proto
|
// source: agent/agent.proto
|
||||||
|
|
||||||
package agent
|
package agent
|
||||||
|
|||||||
@@ -18,11 +18,14 @@ const (
|
|||||||
AlgoTypeKey = "algo_type"
|
AlgoTypeKey = "algo_type"
|
||||||
AlgoArgsKey = "algo_args"
|
AlgoArgsKey = "algo_args"
|
||||||
|
|
||||||
ResultsDir = "results"
|
ResultsDir = "results"
|
||||||
DatasetsDir = "datasets"
|
DatasetsDir = "datasets"
|
||||||
AlgoWorkingDir = "/cocos"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AlgoWorkingDir is the base directory used by algorithm runners (e.g. docker)
|
||||||
|
// to create datasets/results mounts. It is a variable so tests can override it.
|
||||||
|
var AlgoWorkingDir = "/cocos"
|
||||||
|
|
||||||
func AlgorithmTypeToContext(ctx context.Context, algoType string) context.Context {
|
func AlgorithmTypeToContext(ctx context.Context, algoType string) context.Context {
|
||||||
return metadata.AppendToOutgoingContext(ctx, AlgoTypeKey, algoType)
|
return metadata.AppendToOutgoingContext(ctx, AlgoTypeKey, algoType)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,16 @@ func (d *docker) Run() error {
|
|||||||
return fmt.Errorf("could not find image ID")
|
return fmt.Errorf("could not find image ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
datasetsDir := path.Join(algorithm.AlgoWorkingDir, algorithm.DatasetsDir)
|
||||||
|
resultsDir := path.Join(algorithm.AlgoWorkingDir, algorithm.ResultsDir)
|
||||||
|
|
||||||
|
if err := os.MkdirAll(datasetsDir, 0o755); err != nil {
|
||||||
|
return fmt.Errorf("could not create datasets directory %s: %v", datasetsDir, err)
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(resultsDir, 0o755); err != nil {
|
||||||
|
return fmt.Errorf("could not create results directory %s: %v", resultsDir, err)
|
||||||
|
}
|
||||||
|
|
||||||
// Create and start the container.
|
// Create and start the container.
|
||||||
respContainer, err := cli.ContainerCreate(ctx, &container.Config{
|
respContainer, err := cli.ContainerCreate(ctx, &container.Config{
|
||||||
Image: dockerImageName,
|
Image: dockerImageName,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: agent/cvms/cvms.proto
|
// source: agent/cvms/cvms.proto
|
||||||
|
|
||||||
package cvms
|
package cvms
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v7.35.0
|
// - protoc v7.35.1
|
||||||
// source: agent/cvms/cvms.proto
|
// source: agent/cvms/cvms.proto
|
||||||
|
|
||||||
package cvms
|
package cvms
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: agent/events/events.proto
|
// source: agent/events/events.proto
|
||||||
|
|
||||||
package events
|
package events
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: agent/log/log.proto
|
// source: agent/log/log.proto
|
||||||
|
|
||||||
package log
|
package log
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v7.35.0
|
// - protoc v7.35.1
|
||||||
// source: agent/log/log.proto
|
// source: agent/log/log.proto
|
||||||
|
|
||||||
package log
|
package log
|
||||||
|
|||||||
+20
-20
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: agent/runner/runner.proto
|
// source: agent/runner/runner.proto
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
@@ -26,15 +26,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type RunRequest struct {
|
type RunRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
ComputationId string `protobuf:"bytes,1,opt,name=computation_id,json=computationId,proto3" json:"computation_id,omitempty"`
|
ComputationId string `protobuf:"bytes,1,opt,name=computation_id,json=computationId,proto3" json:"computation_id,omitempty"`
|
||||||
AlgoType string `protobuf:"bytes,2,opt,name=algo_type,json=algoType,proto3" json:"algo_type,omitempty"` // "binary", "python", "wasm", "docker"
|
AlgoType string `protobuf:"bytes,2,opt,name=algo_type,json=algoType,proto3" json:"algo_type,omitempty"` // "binary", "python", "wasm", "docker"
|
||||||
Algorithm []byte `protobuf:"bytes,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"` // The algorithm binary/script content
|
AlgorithmPath string `protobuf:"bytes,3,opt,name=algorithm_path,json=algorithmPath,proto3" json:"algorithm_path,omitempty"` // Path to the staged algorithm artifact
|
||||||
Requirements []byte `protobuf:"bytes,4,opt,name=requirements,proto3" json:"requirements,omitempty"` // Python requirements.txt content
|
RequirementsPath string `protobuf:"bytes,4,opt,name=requirements_path,json=requirementsPath,proto3" json:"requirements_path,omitempty"` // Optional path to staged Python requirements.txt
|
||||||
Args []string `protobuf:"bytes,5,rep,name=args,proto3" json:"args,omitempty"`
|
Args []string `protobuf:"bytes,5,rep,name=args,proto3" json:"args,omitempty"`
|
||||||
Datasets []*Dataset `protobuf:"bytes,6,rep,name=datasets,proto3" json:"datasets,omitempty"`
|
Datasets []*Dataset `protobuf:"bytes,6,rep,name=datasets,proto3" json:"datasets,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RunRequest) Reset() {
|
func (x *RunRequest) Reset() {
|
||||||
@@ -81,18 +81,18 @@ func (x *RunRequest) GetAlgoType() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RunRequest) GetAlgorithm() []byte {
|
func (x *RunRequest) GetAlgorithmPath() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Algorithm
|
return x.AlgorithmPath
|
||||||
}
|
}
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RunRequest) GetRequirements() []byte {
|
func (x *RunRequest) GetRequirementsPath() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Requirements
|
return x.RequirementsPath
|
||||||
}
|
}
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RunRequest) GetArgs() []string {
|
func (x *RunRequest) GetArgs() []string {
|
||||||
@@ -261,13 +261,13 @@ var File_agent_runner_runner_proto protoreflect.FileDescriptor
|
|||||||
|
|
||||||
const file_agent_runner_runner_proto_rawDesc = "" +
|
const file_agent_runner_runner_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x19agent/runner/runner.proto\x12\x06runner\x1a\x1bgoogle/protobuf/empty.proto\"\xd3\x01\n" +
|
"\x19agent/runner/runner.proto\x12\x06runner\x1a\x1bgoogle/protobuf/empty.proto\"\xe5\x01\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"RunRequest\x12%\n" +
|
"RunRequest\x12%\n" +
|
||||||
"\x0ecomputation_id\x18\x01 \x01(\tR\rcomputationId\x12\x1b\n" +
|
"\x0ecomputation_id\x18\x01 \x01(\tR\rcomputationId\x12\x1b\n" +
|
||||||
"\talgo_type\x18\x02 \x01(\tR\balgoType\x12\x1c\n" +
|
"\talgo_type\x18\x02 \x01(\tR\balgoType\x12%\n" +
|
||||||
"\talgorithm\x18\x03 \x01(\fR\talgorithm\x12\"\n" +
|
"\x0ealgorithm_path\x18\x03 \x01(\tR\ralgorithmPath\x12+\n" +
|
||||||
"\frequirements\x18\x04 \x01(\fR\frequirements\x12\x12\n" +
|
"\x11requirements_path\x18\x04 \x01(\tR\x10requirementsPath\x12\x12\n" +
|
||||||
"\x04args\x18\x05 \x03(\tR\x04args\x12+\n" +
|
"\x04args\x18\x05 \x03(\tR\x04args\x12+\n" +
|
||||||
"\bdatasets\x18\x06 \x03(\v2\x0f.runner.DatasetR\bdatasets\"9\n" +
|
"\bdatasets\x18\x06 \x03(\v2\x0f.runner.DatasetR\bdatasets\"9\n" +
|
||||||
"\aDataset\x12\x1a\n" +
|
"\aDataset\x12\x1a\n" +
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ service ComputationRunner {
|
|||||||
message RunRequest {
|
message RunRequest {
|
||||||
string computation_id = 1;
|
string computation_id = 1;
|
||||||
string algo_type = 2; // "binary", "python", "wasm", "docker"
|
string algo_type = 2; // "binary", "python", "wasm", "docker"
|
||||||
bytes algorithm = 3; // The algorithm binary/script content
|
string algorithm_path = 3; // Path to the staged algorithm artifact
|
||||||
bytes requirements = 4; // Python requirements.txt content
|
string requirements_path = 4; // Optional path to staged Python requirements.txt
|
||||||
repeated string args = 5;
|
repeated string args = 5;
|
||||||
repeated Dataset datasets = 6;
|
repeated Dataset datasets = 6;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v7.35.0
|
// - protoc v7.35.1
|
||||||
// source: agent/runner/runner.proto
|
// source: agent/runner/runner.proto
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ultravioletrs/cocos/agent/algorithm"
|
"github.com/ultravioletrs/cocos/agent/algorithm"
|
||||||
@@ -20,10 +18,6 @@ import (
|
|||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
algoFilePermission = 0o700
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ pb.ComputationRunnerServer = (*RunnerService)(nil)
|
var _ pb.ComputationRunnerServer = (*RunnerService)(nil)
|
||||||
|
|
||||||
type RunnerService struct {
|
type RunnerService struct {
|
||||||
@@ -58,65 +52,24 @@ func (s *RunnerService) Run(ctx context.Context, req *pb.RunRequest) (*pb.RunRes
|
|||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
currentDir, err := os.Getwd()
|
if req.AlgorithmPath == "" {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("algorithm path is required")
|
||||||
return nil, fmt.Errorf("error getting current directory: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write Algo File
|
|
||||||
algoPath := filepath.Join(currentDir, "algo")
|
|
||||||
f, err := os.Create(algoPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error creating algorithm file: %v", err)
|
|
||||||
}
|
|
||||||
if _, err := f.Write(req.Algorithm); err != nil {
|
|
||||||
return nil, fmt.Errorf("error writing algorithm to file: %v", err)
|
|
||||||
}
|
|
||||||
if err := os.Chmod(algoPath, algoFilePermission); err != nil {
|
|
||||||
return nil, fmt.Errorf("error changing file permissions: %v", err)
|
|
||||||
}
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
return nil, fmt.Errorf("error closing file: %v", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := os.Remove(algoPath); err != nil {
|
|
||||||
s.logger.Warn("error removing algorithm file", "error", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var algo algorithm.Algorithm
|
var algo algorithm.Algorithm
|
||||||
|
|
||||||
switch req.AlgoType {
|
switch req.AlgoType {
|
||||||
case string(algorithm.AlgoTypeBin):
|
case string(algorithm.AlgoTypeBin):
|
||||||
algo = binary.NewAlgorithm(s.logger, s.eventSvc, algoPath, req.Args, req.ComputationId)
|
algo = binary.NewAlgorithm(s.logger, s.eventSvc, req.AlgorithmPath, req.Args, req.ComputationId)
|
||||||
case string(algorithm.AlgoTypePython):
|
case string(algorithm.AlgoTypePython):
|
||||||
var requirementsFile string
|
|
||||||
if len(req.Requirements) > 0 {
|
|
||||||
fr, err := os.CreateTemp("", "requirements.txt")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error creating requirments file: %v", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := os.Remove(fr.Name()); err != nil {
|
|
||||||
s.logger.Warn("error removing requirements file", "error", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if _, err := fr.Write(req.Requirements); err != nil {
|
|
||||||
return nil, fmt.Errorf("error writing requirements to file: %v", err)
|
|
||||||
}
|
|
||||||
if err := fr.Close(); err != nil {
|
|
||||||
return nil, fmt.Errorf("error closing file: %v", err)
|
|
||||||
}
|
|
||||||
requirementsFile = fr.Name()
|
|
||||||
}
|
|
||||||
// Assuming default python runtime if not specified in request (proto doesn't have runtime field yet)
|
// Assuming default python runtime if not specified in request (proto doesn't have runtime field yet)
|
||||||
// We can add it or assume.
|
// We can add it or assume.
|
||||||
runtime := python.PyRuntime
|
runtime := python.PyRuntime
|
||||||
algo = python.NewAlgorithm(s.logger, s.eventSvc, runtime, requirementsFile, algoPath, req.Args, req.ComputationId)
|
algo = python.NewAlgorithm(s.logger, s.eventSvc, runtime, req.RequirementsPath, req.AlgorithmPath, req.Args, req.ComputationId)
|
||||||
case string(algorithm.AlgoTypeWasm):
|
case string(algorithm.AlgoTypeWasm):
|
||||||
algo = wasm.NewAlgorithm(s.logger, s.eventSvc, req.Args, algoPath, req.ComputationId)
|
algo = wasm.NewAlgorithm(s.logger, s.eventSvc, req.Args, req.AlgorithmPath, req.ComputationId)
|
||||||
case string(algorithm.AlgoTypeDocker):
|
case string(algorithm.AlgoTypeDocker):
|
||||||
algo = docker.NewAlgorithm(s.logger, s.eventSvc, algoPath, req.ComputationId)
|
algo = docker.NewAlgorithm(s.logger, s.eventSvc, req.AlgorithmPath, req.ComputationId)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported algorithm type: %s", req.AlgoType)
|
return nil, fmt.Errorf("unsupported algorithm type: %s", req.AlgoType)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/ultravioletrs/cocos/agent/algorithm"
|
||||||
pb "github.com/ultravioletrs/cocos/agent/runner"
|
pb "github.com/ultravioletrs/cocos/agent/runner"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,6 +32,15 @@ func (m *MockEventService) SendEvent(cmpID, event, status string, details json.R
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeRunnerTestFile(t *testing.T, dir, name string, data []byte, mode os.FileMode) string {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
path := filepath.Join(dir, name)
|
||||||
|
require.NoError(t, os.WriteFile(path, data, mode))
|
||||||
|
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
// TestNewRunnerService tests the creation of a new runner service.
|
// TestNewRunnerService tests the creation of a new runner service.
|
||||||
func TestNewRunnerService(t *testing.T) {
|
func TestNewRunnerService(t *testing.T) {
|
||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
@@ -48,6 +59,7 @@ func TestRunWithBinaryAlgorithm(t *testing.T) {
|
|||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
require.NoError(t, os.Chdir(tmpDir))
|
require.NoError(t, os.Chdir(tmpDir))
|
||||||
defer func() { require.NoError(t, os.Chdir(origDir)) }()
|
defer func() { require.NoError(t, os.Chdir(origDir)) }()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo", []byte("#!/bin/bash\necho 'test'"), 0o700)
|
||||||
|
|
||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
@@ -56,7 +68,7 @@ func TestRunWithBinaryAlgorithm(t *testing.T) {
|
|||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-1",
|
ComputationId: "test-1",
|
||||||
AlgoType: "bin",
|
AlgoType: "bin",
|
||||||
Algorithm: []byte("#!/bin/bash\necho 'test'"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{"arg1", "arg2"},
|
Args: []string{"arg1", "arg2"},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,13 +84,16 @@ func TestRunWithPythonAlgorithm(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo.py", []byte("print('hello')"), 0o600)
|
||||||
|
requirementsPath := writeRunnerTestFile(t, tmpDir, "requirements.txt", []byte("numpy==2.2.0"), 0o600)
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-python",
|
ComputationId: "test-python",
|
||||||
AlgoType: "python",
|
AlgoType: "python",
|
||||||
Algorithm: []byte("print('hello')"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
Requirements: []byte("numpy==2.2.0"),
|
RequirementsPath: requirementsPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := rs.Run(context.Background(), req)
|
resp, err := rs.Run(context.Background(), req)
|
||||||
@@ -86,9 +101,6 @@ func TestRunWithPythonAlgorithm(t *testing.T) {
|
|||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
assert.Empty(t, resp.Error)
|
assert.Empty(t, resp.Error)
|
||||||
assert.Equal(t, "test-python", resp.ComputationId)
|
assert.Equal(t, "test-python", resp.ComputationId)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRunWithPythonAlgorithmNoRequirements tests running Python without requirements.
|
// TestRunWithPythonAlgorithmNoRequirements tests running Python without requirements.
|
||||||
@@ -96,11 +108,13 @@ func TestRunWithPythonAlgorithmNoRequirements(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo.py", []byte("print('hello')"), 0o600)
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-python-noreq",
|
ComputationId: "test-python-noreq",
|
||||||
AlgoType: "python",
|
AlgoType: "python",
|
||||||
Algorithm: []byte("print('hello')"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +123,6 @@ func TestRunWithPythonAlgorithmNoRequirements(t *testing.T) {
|
|||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
assert.Empty(t, resp.Error)
|
assert.Empty(t, resp.Error)
|
||||||
assert.Equal(t, "test-python-noreq", resp.ComputationId)
|
assert.Equal(t, "test-python-noreq", resp.ComputationId)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRunWithWasmAlgorithm tests running a WASM algorithm.
|
// TestRunWithWasmAlgorithm tests running a WASM algorithm.
|
||||||
@@ -119,11 +130,13 @@ func TestRunWithWasmAlgorithm(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo.wasm", []byte{0x00, 0x61, 0x73, 0x6d}, 0o600)
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-wasm",
|
ComputationId: "test-wasm",
|
||||||
AlgoType: "wasm",
|
AlgoType: "wasm",
|
||||||
Algorithm: []byte{0x00, 0x61, 0x73, 0x6d},
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,9 +148,6 @@ func TestRunWithWasmAlgorithm(t *testing.T) {
|
|||||||
t.Skip("wasmedge not found, skipping test")
|
t.Skip("wasmedge not found, skipping test")
|
||||||
}
|
}
|
||||||
assert.Equal(t, "test-wasm", resp.ComputationId)
|
assert.Equal(t, "test-wasm", resp.ComputationId)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRunWithDockerAlgorithm tests running a Docker algorithm.
|
// TestRunWithDockerAlgorithm tests running a Docker algorithm.
|
||||||
@@ -145,11 +155,17 @@ func TestRunWithDockerAlgorithm(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "Dockerfile", []byte("FROM ubuntu:latest\nRUN echo 'test'"), 0o600)
|
||||||
|
|
||||||
|
origWorkingDir := algorithm.AlgoWorkingDir
|
||||||
|
algorithm.AlgoWorkingDir = tmpDir
|
||||||
|
t.Cleanup(func() { algorithm.AlgoWorkingDir = origWorkingDir })
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-docker",
|
ComputationId: "test-docker",
|
||||||
AlgoType: "docker",
|
AlgoType: "docker",
|
||||||
Algorithm: []byte("FROM ubuntu:latest\nRUN echo 'test'"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,9 +177,6 @@ func TestRunWithDockerAlgorithm(t *testing.T) {
|
|||||||
t.Skip("Docker issue, skipping test")
|
t.Skip("Docker issue, skipping test")
|
||||||
}
|
}
|
||||||
assert.Equal(t, "test-docker", resp.ComputationId)
|
assert.Equal(t, "test-docker", resp.ComputationId)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRunWithUnsupportedAlgorithmType tests running with unsupported algorithm type.
|
// TestRunWithUnsupportedAlgorithmType tests running with unsupported algorithm type.
|
||||||
@@ -175,7 +188,7 @@ func TestRunWithUnsupportedAlgorithmType(t *testing.T) {
|
|||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-unsupported",
|
ComputationId: "test-unsupported",
|
||||||
AlgoType: "unsupported",
|
AlgoType: "unsupported",
|
||||||
Algorithm: []byte("test"),
|
AlgorithmPath: "/tmp/test",
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,12 +202,14 @@ func TestRunAlreadyRunning(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo", []byte("#!/bin/bash\nsleep 30"), 0o700)
|
||||||
|
|
||||||
// Use a long-running bash script
|
// Use a long-running bash script
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-running",
|
ComputationId: "test-running",
|
||||||
AlgoType: "bin",
|
AlgoType: "bin",
|
||||||
Algorithm: []byte("#!/bin/bash\nsleep 30"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,9 +226,6 @@ func TestRunAlreadyRunning(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
assert.Equal(t, "computation already running", resp.Error)
|
assert.Equal(t, "computation already running", resp.Error)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestStopWhenRunning tests stopping a running computation.
|
// TestStopWhenRunning tests stopping a running computation.
|
||||||
@@ -221,11 +233,13 @@ func TestStopWhenRunning(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo", []byte("#!/bin/bash\nsleep 10"), 0o700)
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-stop",
|
ComputationId: "test-stop",
|
||||||
AlgoType: "bin",
|
AlgoType: "bin",
|
||||||
Algorithm: []byte("#!/bin/bash\nsleep 10"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,9 +257,6 @@ func TestStopWhenRunning(t *testing.T) {
|
|||||||
stopResp, err := rs.Stop(context.Background(), stopReq)
|
stopResp, err := rs.Stop(context.Background(), stopReq)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, stopResp)
|
require.NotNil(t, stopResp)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRunErrors tests error paths in Run.
|
// TestRunErrors tests error paths in Run.
|
||||||
@@ -255,59 +266,27 @@ func TestRunErrors(t *testing.T) {
|
|||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
|
||||||
t.Run("create algo file failure", func(t *testing.T) {
|
t.Run("create algo file failure", func(t *testing.T) {
|
||||||
// Create a directory named "algo" to make os.Create("algo") fail
|
var err error
|
||||||
err := os.Mkdir("algo", 0o755)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer os.RemoveAll("algo")
|
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-err",
|
ComputationId: "test-err",
|
||||||
AlgoType: "bin",
|
AlgoType: "bin",
|
||||||
Algorithm: []byte("test"),
|
AlgorithmPath: "",
|
||||||
}
|
}
|
||||||
_, err = rs.Run(context.Background(), req)
|
_, err = rs.Run(context.Background(), req)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), "error creating algorithm file")
|
assert.Contains(t, err.Error(), "algorithm path is required")
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("getwd failure", func(t *testing.T) {
|
|
||||||
origDir, _ := os.Getwd()
|
|
||||||
tmpDir := t.TempDir()
|
|
||||||
err := os.Chdir(tmpDir)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Remove the current working directory to trigger Getwd failure
|
|
||||||
err = os.RemoveAll(tmpDir)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
|
||||||
ComputationId: "test-err-getwd",
|
|
||||||
AlgoType: "bin",
|
|
||||||
Algorithm: []byte("test"),
|
|
||||||
}
|
|
||||||
_, err = rs.Run(context.Background(), req)
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Contains(t, err.Error(), "error getting current directory")
|
|
||||||
|
|
||||||
// Restore working directory
|
|
||||||
_ = os.Chdir(origDir)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("requirements file creation failure", func(t *testing.T) {
|
t.Run("requirements file creation failure", func(t *testing.T) {
|
||||||
// This one is harder because it uses os.CreateTemp("", "requirements.txt")
|
// Requirements are now staged by the agent, so the runner no longer creates temp files.
|
||||||
// We can't easily make this fail without reaching into the system's temp dir.
|
|
||||||
// Skipping for now as it's a very unlikely edge case.
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("chmod failure", func(t *testing.T) {
|
t.Run("chmod failure", func(t *testing.T) {
|
||||||
// We can't easily mock os.Chmod, but we can try to make the file unmodifiable
|
// Permission management is now the agent's responsibility during staging.
|
||||||
// On Linux, we can set the immutable attribute, but that requires root.
|
|
||||||
// Alternatively, we can try to use a directory with permissions that prevent chmod?
|
|
||||||
// No, chmod usually works if you own the file.
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("write algorithm failure", func(t *testing.T) {
|
t.Run("write algorithm failure", func(t *testing.T) {
|
||||||
// This is also hard without mocking os.File.Write or reaching internal limits.
|
// Write failures are now handled by the agent before invoking the runner.
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,11 +295,13 @@ func TestConcurrentRun(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo", []byte("#!/bin/bash\nsleep 15"), 0o700)
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-concurrent",
|
ComputationId: "test-concurrent",
|
||||||
AlgoType: "bin",
|
AlgoType: "bin",
|
||||||
Algorithm: []byte("#!/bin/bash\nsleep 15"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,9 +317,6 @@ func TestConcurrentRun(t *testing.T) {
|
|||||||
resp2, err := rs.Run(context.Background(), req)
|
resp2, err := rs.Run(context.Background(), req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "computation already running", resp2.Error)
|
assert.Equal(t, "computation already running", resp2.Error)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRunWithMultipleArgs tests running with multiple arguments.
|
// TestRunWithMultipleArgs tests running with multiple arguments.
|
||||||
@@ -346,11 +324,13 @@ func TestRunWithMultipleArgs(t *testing.T) {
|
|||||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||||
eventSvc := &MockEventService{}
|
eventSvc := &MockEventService{}
|
||||||
rs := New(logger, eventSvc)
|
rs := New(logger, eventSvc)
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
algoPath := writeRunnerTestFile(t, tmpDir, "algo", []byte("#!/bin/bash\necho $@"), 0o700)
|
||||||
|
|
||||||
req := &pb.RunRequest{
|
req := &pb.RunRequest{
|
||||||
ComputationId: "test-multi-args",
|
ComputationId: "test-multi-args",
|
||||||
AlgoType: "bin",
|
AlgoType: "bin",
|
||||||
Algorithm: []byte("#!/bin/bash\necho $@"),
|
AlgorithmPath: algoPath,
|
||||||
Args: []string{"arg1", "arg2", "arg3", "arg4"},
|
Args: []string{"arg1", "arg2", "arg3", "arg4"},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,9 +339,6 @@ func TestRunWithMultipleArgs(t *testing.T) {
|
|||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
assert.Empty(t, resp.Error)
|
assert.Empty(t, resp.Error)
|
||||||
assert.Equal(t, "test-multi-args", resp.ComputationId)
|
assert.Equal(t, "test-multi-args", resp.ComputationId)
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.Remove("algo")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStopFailure(t *testing.T) {
|
func TestStopFailure(t *testing.T) {
|
||||||
|
|||||||
+77
-32
@@ -82,7 +82,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
algoFilePermission = 0o700
|
algoFilePermission = 0o700
|
||||||
|
algoFileName = "algo"
|
||||||
|
requirementsFileName = "requirements.txt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -113,6 +115,30 @@ func ensureDir(path string, mode os.FileMode) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeFile(path string, data []byte, mode os.FileMode) error {
|
||||||
|
if err := os.WriteFile(path, data, mode); err != nil {
|
||||||
|
return fmt.Errorf("writing file %q: %w", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func stageRequirementsFile(workDir string, requirements []byte) (string, error) {
|
||||||
|
requirementsPath := filepath.Join(workDir, requirementsFileName)
|
||||||
|
if len(requirements) == 0 {
|
||||||
|
if err := os.Remove(requirementsPath); err != nil && !os.IsNotExist(err) {
|
||||||
|
return "", fmt.Errorf("removing stale requirements file: %w", err)
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeFile(requirementsPath, requirements, 0o600); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return requirementsPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrMalformedEntity indicates malformed entity specification (e.g.
|
// ErrMalformedEntity indicates malformed entity specification (e.g.
|
||||||
// invalid username or password).
|
// invalid username or password).
|
||||||
@@ -364,10 +390,14 @@ func (as *agentService) StopComputation(ctx context.Context) error {
|
|||||||
return fmt.Errorf("error removing results directory: %v", err)
|
return fmt.Errorf("error removing results directory: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Remove("algo"); err != nil && !os.IsNotExist(err) {
|
if err := os.Remove(algoFileName); err != nil && !os.IsNotExist(err) {
|
||||||
as.logger.Warn("error removing algorithm file", "error", err)
|
as.logger.Warn("error removing algorithm file", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := os.Remove(requirementsFileName); err != nil && !os.IsNotExist(err) {
|
||||||
|
as.logger.Warn("error removing requirements file", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
as.sm.Reset(Idle)
|
as.sm.Reset(Idle)
|
||||||
|
|
||||||
as.computation = Computation{}
|
as.computation = Computation{}
|
||||||
@@ -448,9 +478,9 @@ func (as *agentService) downloadAlgorithmIfRemote(state statemachine.State) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write algorithm to file
|
// Write algorithm to file
|
||||||
currentDir, err := os.Getwd()
|
currentDir, getwdErr := os.Getwd()
|
||||||
if err != nil {
|
if getwdErr != nil {
|
||||||
as.runError = fmt.Errorf("error getting current directory: %w", err)
|
as.runError = fmt.Errorf("error getting current directory: %w", getwdErr)
|
||||||
as.logger.Error(as.runError.Error())
|
as.logger.Error(as.runError.Error())
|
||||||
as.sm.SendEvent(RunFailed)
|
as.sm.SendEvent(RunFailed)
|
||||||
return
|
return
|
||||||
@@ -504,7 +534,14 @@ func (as *agentService) downloadAlgorithmIfRemote(state statemachine.State) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
as.algoReceived = true
|
as.algoReceived = true
|
||||||
as.algoRequirements = res.Requirements // Store requirements for installation
|
as.algoRequirements = res.Requirements
|
||||||
|
|
||||||
|
if _, err := stageRequirementsFile(currentDir, as.algoRequirements); err != nil {
|
||||||
|
as.runError = fmt.Errorf("error staging requirements file: %w", err)
|
||||||
|
as.logger.Error(as.runError.Error())
|
||||||
|
as.sm.SendEvent(RunFailed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// The initramfs may have already provisioned /cocos/datasets.
|
// The initramfs may have already provisioned /cocos/datasets.
|
||||||
if err := ensureDir(algorithm.DatasetsDir, 0o755); err != nil {
|
if err := ensureDir(algorithm.DatasetsDir, 0o755); err != nil {
|
||||||
@@ -1053,21 +1090,9 @@ func (as *agentService) Algo(ctx context.Context, algo Algorithm) error {
|
|||||||
return fmt.Errorf("error getting current directory: %v", err)
|
return fmt.Errorf("error getting current directory: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Create(filepath.Join(currentDir, "algo"))
|
algoPath := filepath.Join(currentDir, algoFileName)
|
||||||
if err != nil {
|
if err := writeFile(algoPath, algoData, algoFilePermission); err != nil {
|
||||||
return fmt.Errorf("error creating algorithm file: %v", err)
|
return fmt.Errorf("error staging algorithm file: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := f.Write(algoData); err != nil {
|
|
||||||
return fmt.Errorf("error writing algorithm to file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.Chmod(f.Name(), algoFilePermission); err != nil {
|
|
||||||
return fmt.Errorf("error changing file permissions: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
return fmt.Errorf("error closing file: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
algoType := algorithm.AlgorithmTypeFromContext(ctx)
|
algoType := algorithm.AlgorithmTypeFromContext(ctx)
|
||||||
@@ -1079,7 +1104,13 @@ func (as *agentService) Algo(ctx context.Context, algo Algorithm) error {
|
|||||||
|
|
||||||
as.algoType = algoType
|
as.algoType = algoType
|
||||||
as.algoArgs = args
|
as.algoArgs = args
|
||||||
as.algoRequirements = algo.Requirements
|
if len(as.algoRequirements) == 0 {
|
||||||
|
as.algoRequirements = algo.Requirements
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := stageRequirementsFile(currentDir, as.algoRequirements); err != nil {
|
||||||
|
return fmt.Errorf("error staging requirements file: %w", err)
|
||||||
|
}
|
||||||
as.algoReceived = true
|
as.algoReceived = true
|
||||||
|
|
||||||
if err := ensureDir(algorithm.DatasetsDir, 0o755); err != nil {
|
if err := ensureDir(algorithm.DatasetsDir, 0o755); err != nil {
|
||||||
@@ -1276,9 +1307,9 @@ func (as *agentService) runComputation(state statemachine.State) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Read algo file
|
|
||||||
currentDir, _ := os.Getwd()
|
currentDir, _ := os.Getwd()
|
||||||
algoFile := filepath.Join(currentDir, "algo")
|
algoFile := filepath.Join(currentDir, algoFileName)
|
||||||
|
requirementsFile := filepath.Join(currentDir, requirementsFileName)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := os.RemoveAll(algorithm.ResultsDir); err != nil {
|
if err := os.RemoveAll(algorithm.ResultsDir); err != nil {
|
||||||
@@ -1290,6 +1321,9 @@ func (as *agentService) runComputation(state statemachine.State) {
|
|||||||
if err := os.Remove(algoFile); err != nil && !os.IsNotExist(err) {
|
if err := os.Remove(algoFile); err != nil && !os.IsNotExist(err) {
|
||||||
as.logger.Warn(fmt.Sprintf("error removing algorithm file: %s", err.Error()))
|
as.logger.Warn(fmt.Sprintf("error removing algorithm file: %s", err.Error()))
|
||||||
}
|
}
|
||||||
|
if err := os.Remove(requirementsFile); err != nil && !os.IsNotExist(err) {
|
||||||
|
as.logger.Warn(fmt.Sprintf("error removing requirements file: %s", err.Error()))
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := ensureDir(algorithm.ResultsDir, 0o755); err != nil {
|
if err := ensureDir(algorithm.ResultsDir, 0o755); err != nil {
|
||||||
@@ -1301,10 +1335,21 @@ func (as *agentService) runComputation(state statemachine.State) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
algoBytes, err := os.ReadFile(algoFile)
|
if _, err := os.Stat(algoFile); err != nil {
|
||||||
if err != nil {
|
|
||||||
as.mu.Lock()
|
as.mu.Lock()
|
||||||
as.runError = fmt.Errorf("failed to read algo file: %w", err)
|
as.runError = fmt.Errorf("failed to stat algo file: %w", err)
|
||||||
|
as.mu.Unlock()
|
||||||
|
as.logger.Warn(as.runError.Error())
|
||||||
|
as.publishEvent(Failed.String())(state)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
requirementsPath := ""
|
||||||
|
if _, err := os.Stat(requirementsFile); err == nil {
|
||||||
|
requirementsPath = requirementsFile
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
as.mu.Lock()
|
||||||
|
as.runError = fmt.Errorf("failed to stat requirements file: %w", err)
|
||||||
as.mu.Unlock()
|
as.mu.Unlock()
|
||||||
as.logger.Warn(as.runError.Error())
|
as.logger.Warn(as.runError.Error())
|
||||||
as.publishEvent(Failed.String())(state)
|
as.publishEvent(Failed.String())(state)
|
||||||
@@ -1315,11 +1360,11 @@ func (as *agentService) runComputation(state statemachine.State) {
|
|||||||
|
|
||||||
// Call Runner
|
// Call Runner
|
||||||
resp, err := as.runnerClient.Run(context.Background(), &runnerpb.RunRequest{
|
resp, err := as.runnerClient.Run(context.Background(), &runnerpb.RunRequest{
|
||||||
ComputationId: as.computation.ID,
|
ComputationId: as.computation.ID,
|
||||||
AlgoType: as.algoType,
|
AlgoType: as.algoType,
|
||||||
Algorithm: algoBytes,
|
AlgorithmPath: algoFile,
|
||||||
Requirements: as.algoRequirements,
|
RequirementsPath: requirementsPath,
|
||||||
Args: as.algoArgs,
|
Args: as.algoArgs,
|
||||||
// Datasets implicit on shared FS
|
// Datasets implicit on shared FS
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1014,7 +1014,7 @@ func TestRunComputation(t *testing.T) {
|
|||||||
svc.runComputation(Running)
|
svc.runComputation(Running)
|
||||||
|
|
||||||
assert.Error(t, svc.runError)
|
assert.Error(t, svc.runError)
|
||||||
assert.Contains(t, svc.runError.Error(), "failed to read algo file")
|
assert.Contains(t, svc.runError.Error(), "failed to stat algo file")
|
||||||
sm.AssertExpectations(t)
|
sm.AssertExpectations(t)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1026,7 +1026,9 @@ func TestRunComputation(t *testing.T) {
|
|||||||
require.NoError(t, os.WriteFile("algo", []byte("#!/bin/sh\necho ok\n"), 0o755))
|
require.NoError(t, os.WriteFile("algo", []byte("#!/bin/sh\necho ok\n"), 0o755))
|
||||||
|
|
||||||
runnerCli := new(runnermocks.Client)
|
runnerCli := new(runnermocks.Client)
|
||||||
runnerCli.On("Run", mock.Anything, mock.Anything).Return((*runnerpb.RunResponse)(nil), fmt.Errorf("runner unavailable"))
|
runnerCli.On("Run", mock.Anything, mock.MatchedBy(func(req *runnerpb.RunRequest) bool {
|
||||||
|
return req != nil && filepath.Base(req.AlgorithmPath) == algoFileName && req.RequirementsPath == "" && len(req.Args) == 0
|
||||||
|
})).Return((*runnerpb.RunResponse)(nil), fmt.Errorf("runner unavailable"))
|
||||||
|
|
||||||
eventsSvc := new(mocks.Service)
|
eventsSvc := new(mocks.Service)
|
||||||
eventsSvc.EXPECT().SendEvent(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return().Maybe()
|
eventsSvc.EXPECT().SendEvent(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return().Maybe()
|
||||||
|
|||||||
+11
-11
@@ -15,8 +15,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/absmach/certs/sdk"
|
|
||||||
mglog "github.com/absmach/magistrala/logger"
|
mglog "github.com/absmach/magistrala/logger"
|
||||||
"github.com/absmach/magistrala/pkg/prometheus"
|
"github.com/absmach/magistrala/pkg/prometheus"
|
||||||
"github.com/caarlos0/env/v11"
|
"github.com/caarlos0/env/v11"
|
||||||
@@ -52,9 +52,7 @@ type config struct {
|
|||||||
LogLevel string `env:"AGENT_LOG_LEVEL" envDefault:"debug"`
|
LogLevel string `env:"AGENT_LOG_LEVEL" envDefault:"debug"`
|
||||||
Vmpl int `env:"AGENT_VMPL" envDefault:"2"`
|
Vmpl int `env:"AGENT_VMPL" envDefault:"2"`
|
||||||
AgentGrpcHost string `env:"AGENT_GRPC_HOST" envDefault:"0.0.0.0"`
|
AgentGrpcHost string `env:"AGENT_GRPC_HOST" envDefault:"0.0.0.0"`
|
||||||
CAUrl string `env:"AGENT_CVM_CA_URL" envDefault:""`
|
|
||||||
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
||||||
CertsToken string `env:"AGENT_CERTS_TOKEN" envDefault:""`
|
|
||||||
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
||||||
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
||||||
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
||||||
@@ -215,13 +213,7 @@ func main() {
|
|||||||
var certProvider atls.CertificateProvider
|
var certProvider atls.CertificateProvider
|
||||||
if ccPlatform != attestation.NoCC {
|
if ccPlatform != attestation.NoCC {
|
||||||
logger.Info(fmt.Sprintf("Initializing aTLS for platform %v with attestation service at %s", ccPlatform, cfg.AttestationServiceSocket))
|
logger.Info(fmt.Sprintf("Initializing aTLS for platform %v with attestation service at %s", ccPlatform, cfg.AttestationServiceSocket))
|
||||||
var certsSDK sdk.SDK
|
certProvider, err = atls.NewProvider(attClient, ccPlatform)
|
||||||
if cfg.CAUrl != "" {
|
|
||||||
certsSDK = sdk.NewSDK(sdk.Config{
|
|
||||||
CertsURL: cfg.CAUrl,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
certProvider, err = atls.NewProvider(attClient, ccPlatform, cfg.CertsToken, cfg.CVMId, certsSDK)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(fmt.Sprintf("failed to create certificate provider for aTLS: %s. Continuing without attested TLS.", err))
|
logger.Error(fmt.Sprintf("failed to create certificate provider for aTLS: %s. Continuing without attested TLS.", err))
|
||||||
} else {
|
} else {
|
||||||
@@ -274,7 +266,15 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return mc.Process(ctx, cancel)
|
for {
|
||||||
|
if err := mc.Process(ctx, cancel); err != nil {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
logger.Warn("CVMS client process connection loop exited, retrying in 2s...", "error", err)
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
attest, certSerialNumber, err := attestationFromCert(ctx, cvmGrpcConfig.ClientCert, svc, ccPlatform)
|
attest, certSerialNumber, err := attestationFromCert(ctx, cvmGrpcConfig.ClientCert, svc, ccPlatform)
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/absmach/certs/sdk"
|
|
||||||
"github.com/caarlos0/env/v11"
|
"github.com/caarlos0/env/v11"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@@ -36,9 +35,7 @@ type config struct {
|
|||||||
Backend string `env:"COCOS_INGRESS_BACKEND" envDefault:"http://localhost:7001"`
|
Backend string `env:"COCOS_INGRESS_BACKEND" envDefault:"http://localhost:7001"`
|
||||||
|
|
||||||
// ATLS Config
|
// ATLS Config
|
||||||
CAUrl string `env:"AGENT_CVM_CA_URL" envDefault:""`
|
|
||||||
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
||||||
CertsToken string `env:"AGENT_CERTS_TOKEN" envDefault:""`
|
|
||||||
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
||||||
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
||||||
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
||||||
@@ -143,13 +140,7 @@ func run(cfg config) error {
|
|||||||
}
|
}
|
||||||
defer attClient.Close()
|
defer attClient.Close()
|
||||||
|
|
||||||
var certsSDK sdk.SDK
|
certProvider, err = atls.NewProvider(attClient, ccPlatform)
|
||||||
if cfg.CAUrl != "" {
|
|
||||||
certsSDK = sdk.NewSDK(sdk.Config{
|
|
||||||
CertsURL: cfg.CAUrl,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
certProvider, err = atls.NewProvider(attClient, ccPlatform, cfg.CertsToken, cfg.CVMId, certsSDK)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create certificate provider: %w", err)
|
return fmt.Errorf("failed to create certificate provider: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ require (
|
|||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect
|
||||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
github.com/absmach/supermq v0.19.2-0.20260317185610-fade98b84ee4 // indirect
|
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
|
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
|
||||||
github.com/containerd/errdefs v1.0.0 // indirect
|
github.com/containerd/errdefs v1.0.0 // indirect
|
||||||
@@ -103,11 +102,9 @@ require (
|
|||||||
golang.org/x/time v0.15.0 // indirect
|
golang.org/x/time v0.15.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect
|
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect
|
||||||
gotest.tools/v3 v3.5.1 // indirect
|
gotest.tools/v3 v3.5.1 // indirect
|
||||||
moul.io/http2curl v1.0.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/absmach/certs v0.18.5
|
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
|
|||||||
@@ -34,12 +34,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
|
|||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
|
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
github.com/absmach/certs v0.18.5 h1:eYlvitou+LoDtt7ETVLTp6d/1xCejGL3EmVOg+rHGTU=
|
|
||||||
github.com/absmach/certs v0.18.5/go.mod h1:31dtVe1VYF16W+IvjAE/uPAIz4f3uLHgh+moBezjqIc=
|
|
||||||
github.com/absmach/magistrala v0.20.0 h1:3AQ0C2AMoOCc1UuJLhPNJLMrNRLZoN0ibSOERqEkM98=
|
github.com/absmach/magistrala v0.20.0 h1:3AQ0C2AMoOCc1UuJLhPNJLMrNRLZoN0ibSOERqEkM98=
|
||||||
github.com/absmach/magistrala v0.20.0/go.mod h1:lnuO4fSngMiRYyNYL4yz5UP8DX3bbXRm87b2KHFGwJU=
|
github.com/absmach/magistrala v0.20.0/go.mod h1:lnuO4fSngMiRYyNYL4yz5UP8DX3bbXRm87b2KHFGwJU=
|
||||||
github.com/absmach/supermq v0.19.2-0.20260317185610-fade98b84ee4 h1:533pRc6R7perWDqJuZq+ofBQfYfmyj7n49V4LFY4zpo=
|
|
||||||
github.com/absmach/supermq v0.19.2-0.20260317185610-fade98b84ee4/go.mod h1:xDAX/O3VcOsHWCx2fk85VD7FI17hAUOvoOhho7DA7g0=
|
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA=
|
github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA=
|
||||||
@@ -94,8 +90,6 @@ github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sa
|
|||||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||||
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
||||||
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
||||||
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
|
|
||||||
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
|
||||||
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
|
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||||
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
|
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
|
||||||
@@ -156,24 +150,10 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA
|
|||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg=
|
||||||
github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI=
|
github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI=
|
||||||
github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4=
|
github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4=
|
||||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
|
||||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
|
||||||
github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc=
|
|
||||||
github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
|
|
||||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
|
||||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
|
||||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
|
||||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
|
||||||
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||||
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
@@ -231,8 +211,6 @@ github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4
|
|||||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/rubenv/sql-migrate v1.8.1 h1:EPNwCvjAowHI3TnZ+4fQu3a915OpnQoPAjTXCGOy2U0=
|
|
||||||
github.com/rubenv/sql-migrate v1.8.1/go.mod h1:BTIKBORjzyxZDS6dzoiw6eAFYJ1iNlGAtjn4LGeVjS8=
|
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sammyoina/sev-snp-measure-go v0.0.0-20241202151803-ef189f0ff825 h1:SqNaL9udBIc026SGNEuEuiVL0/hw9fXxM5qrFhWGkdE=
|
github.com/sammyoina/sev-snp-measure-go v0.0.0-20241202151803-ef189f0ff825 h1:SqNaL9udBIc026SGNEuEuiVL0/hw9fXxM5qrFhWGkdE=
|
||||||
github.com/sammyoina/sev-snp-measure-go v0.0.0-20241202151803-ef189f0ff825/go.mod h1:dEkBe8JnxU5itNjZDEQINFd7f7l4DtjfqRuzPQcit4w=
|
github.com/sammyoina/sev-snp-measure-go v0.0.0-20241202151803-ef189f0ff825/go.mod h1:dEkBe8JnxU5itNjZDEQINFd7f7l4DtjfqRuzPQcit4w=
|
||||||
@@ -240,10 +218,6 @@ github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
|
|||||||
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY=
|
|
||||||
github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI=
|
|
||||||
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
|
|
||||||
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
|
|
||||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||||
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||||
@@ -382,5 +356,3 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||||
moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8=
|
|
||||||
moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE=
|
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_COCOS_PATH)/board/cocos/post-image.
|
|||||||
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_DEFCONFIG)"
|
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_DEFCONFIG)"
|
||||||
|
|
||||||
# Linux headers same as kernel
|
# Linux headers same as kernel
|
||||||
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_6_11=y
|
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_7_0=y
|
||||||
BR2_TOOLCHAIN_HEADERS_LATEST=y
|
BR2_TOOLCHAIN_HEADERS_LATEST=y
|
||||||
BR2_TOOLCHAIN_HEADERS_AT_LEAST="6.11-rc7"
|
BR2_TOOLCHAIN_HEADERS_AT_LEAST="7.0"
|
||||||
|
|
||||||
# Kernel
|
# Kernel
|
||||||
BR2_LINUX_KERNEL=y
|
BR2_LINUX_KERNEL=y
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_CGROUPS=y
|
CONFIG_CGROUPS=y
|
||||||
|
CONFIG_CGROUP_DEVICE=y
|
||||||
|
CONFIG_CGROUP_PIDS=y
|
||||||
|
CONFIG_MEMCG=y
|
||||||
|
CONFIG_BLK_CGROUP=y
|
||||||
CONFIG_MODULES=y
|
CONFIG_MODULES=y
|
||||||
CONFIG_MODULE_UNLOAD=y
|
CONFIG_MODULE_UNLOAD=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
|
CONFIG_NAMESPACES=y
|
||||||
|
CONFIG_UTS_NS=y
|
||||||
|
CONFIG_IPC_NS=y
|
||||||
|
CONFIG_USER_NS=y
|
||||||
|
CONFIG_PID_NS=y
|
||||||
|
CONFIG_NET_NS=y
|
||||||
CONFIG_HYPERVISOR_GUEST=y
|
CONFIG_HYPERVISOR_GUEST=y
|
||||||
CONFIG_PARAVIRT=y
|
CONFIG_PARAVIRT=y
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
@@ -14,12 +24,17 @@ CONFIG_PCI=y
|
|||||||
CONFIG_DEVTMPFS=y
|
CONFIG_DEVTMPFS=y
|
||||||
CONFIG_DEVTMPFS_MOUNT=y
|
CONFIG_DEVTMPFS_MOUNT=y
|
||||||
CONFIG_VIRTIO_BLK=y
|
CONFIG_VIRTIO_BLK=y
|
||||||
|
CONFIG_BLK_DEV_LOOP=y
|
||||||
|
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
|
||||||
CONFIG_BLK_DEV_SD=y
|
CONFIG_BLK_DEV_SD=y
|
||||||
CONFIG_SCSI_VIRTIO=y
|
CONFIG_SCSI_VIRTIO=y
|
||||||
CONFIG_ATA=y
|
CONFIG_ATA=y
|
||||||
CONFIG_ATA_PIIX=y
|
CONFIG_ATA_PIIX=y
|
||||||
CONFIG_NETDEVICES=y
|
CONFIG_NETDEVICES=y
|
||||||
CONFIG_VIRTIO_NET=y
|
CONFIG_VIRTIO_NET=y
|
||||||
|
CONFIG_VETH=y
|
||||||
|
CONFIG_BRIDGE=y
|
||||||
|
CONFIG_BRIDGE_NETFILTER=y
|
||||||
CONFIG_NE2K_PCI=y
|
CONFIG_NE2K_PCI=y
|
||||||
CONFIG_8139CP=y
|
CONFIG_8139CP=y
|
||||||
# CONFIG_WLAN is not set
|
# CONFIG_WLAN is not set
|
||||||
@@ -34,15 +49,43 @@ CONFIG_VIRTIO_INPUT=y
|
|||||||
CONFIG_VIRTIO_MMIO=y
|
CONFIG_VIRTIO_MMIO=y
|
||||||
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
|
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
|
||||||
CONFIG_EXT4_FS=y
|
CONFIG_EXT4_FS=y
|
||||||
|
CONFIG_OVERLAY_FS=y
|
||||||
CONFIG_AUTOFS4_FS=y
|
CONFIG_AUTOFS4_FS=y
|
||||||
CONFIG_TMPFS=y
|
CONFIG_TMPFS=y
|
||||||
CONFIG_TMPFS_POSIX_ACL=y
|
CONFIG_TMPFS_POSIX_ACL=y
|
||||||
|
CONFIG_FHANDLE=y
|
||||||
|
CONFIG_INOTIFY_USER=y
|
||||||
|
CONFIG_SIGNALFD=y
|
||||||
|
CONFIG_TIMERFD=y
|
||||||
|
CONFIG_EPOLL=y
|
||||||
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||||
CONFIG_UNWINDER_FRAME_POINTER=y
|
CONFIG_UNWINDER_FRAME_POINTER=y
|
||||||
CONFIG_VSOCKETS=y
|
CONFIG_VSOCKETS=y
|
||||||
CONFIG_VIRTIO_VSOCKETS=y
|
CONFIG_VIRTIO_VSOCKETS=y
|
||||||
|
CONFIG_NETFILTER=y
|
||||||
|
CONFIG_NETFILTER_ADVANCED=y
|
||||||
|
CONFIG_NETFILTER_XTABLES_LEGACY=y
|
||||||
|
CONFIG_NF_CONNTRACK=y
|
||||||
|
CONFIG_NF_CONNTRACK_MARK=y
|
||||||
|
CONFIG_NF_NAT=y
|
||||||
|
CONFIG_NF_NAT_MASQUERADE=y
|
||||||
|
CONFIG_NETFILTER_XTABLES=y
|
||||||
|
CONFIG_NETFILTER_XT_NAT=y
|
||||||
|
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y
|
||||||
|
CONFIG_NF_DEFRAG_IPV4=y
|
||||||
|
CONFIG_IP_NF_IPTABLES_LEGACY=y
|
||||||
|
CONFIG_IP_NF_IPTABLES=y
|
||||||
|
CONFIG_IP_NF_FILTER=y
|
||||||
|
CONFIG_IP_NF_NAT=y
|
||||||
|
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||||
|
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
|
||||||
|
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||||
CONFIG_NF_TABLES=y
|
CONFIG_NF_TABLES=y
|
||||||
CONFIG_BPF_SYSCALL=y
|
CONFIG_BPF_SYSCALL=y
|
||||||
CONFIG_CGROUP_BPF=y
|
CONFIG_CGROUP_BPF=y
|
||||||
|
CONFIG_SECCOMP=y
|
||||||
|
CONFIG_SECCOMP_FILTER=y
|
||||||
|
|
||||||
###
|
###
|
||||||
# AMD SEV-SNP
|
# AMD SEV-SNP
|
||||||
|
|||||||
@@ -19,15 +19,18 @@ BR2_PACKAGE_9PFS=y
|
|||||||
|
|
||||||
# Image
|
# Image
|
||||||
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_COCOS_PATH)/board/cocos/post-build.sh"
|
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_COCOS_PATH)/board/cocos/post-build.sh"
|
||||||
|
|
||||||
|
# Patches for existing Buildroot packages
|
||||||
|
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_COCOS_PATH)/patches"
|
||||||
|
|
||||||
# Image
|
# Image
|
||||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_COCOS_PATH)/board/cocos/post-image.sh"
|
BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_COCOS_PATH)/board/cocos/post-image.sh"
|
||||||
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_DEFCONFIG)"
|
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_DEFCONFIG)"
|
||||||
|
|
||||||
# Linux headers same as kernel
|
# Linux headers same as kernel
|
||||||
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_6_11=y
|
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_7_0=y
|
||||||
BR2_TOOLCHAIN_HEADERS_LATEST=y
|
BR2_TOOLCHAIN_HEADERS_LATEST=y
|
||||||
BR2_TOOLCHAIN_HEADERS_AT_LEAST="6.11-rc7"
|
BR2_TOOLCHAIN_HEADERS_AT_LEAST="7.0"
|
||||||
|
|
||||||
# Kernel
|
# Kernel
|
||||||
BR2_LINUX_KERNEL=y
|
BR2_LINUX_KERNEL=y
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ define AGENT_INSTALL_INIT_SYSTEMD
|
|||||||
$(INSTALL) -D -m 0640 $(@D)/init/systemd/cocos-agent.service $(TARGET_DIR)/usr/lib/systemd/system/cocos-agent.service
|
$(INSTALL) -D -m 0640 $(@D)/init/systemd/cocos-agent.service $(TARGET_DIR)/usr/lib/systemd/system/cocos-agent.service
|
||||||
$(INSTALL) -D -m 0750 $(@D)/init/systemd/agent_setup.sh $(TARGET_DIR)/cocos_init/agent_setup.sh
|
$(INSTALL) -D -m 0750 $(@D)/init/systemd/agent_setup.sh $(TARGET_DIR)/cocos_init/agent_setup.sh
|
||||||
$(INSTALL) -D -m 0750 $(@D)/init/systemd/agent_start_script.sh $(TARGET_DIR)/cocos_init/agent_start_script.sh
|
$(INSTALL) -D -m 0750 $(@D)/init/systemd/agent_start_script.sh $(TARGET_DIR)/cocos_init/agent_start_script.sh
|
||||||
|
mkdir -p $(TARGET_DIR)/usr/lib/systemd/system/multi-user.target.wants
|
||||||
|
ln -sf ../docker.service $(TARGET_DIR)/usr/lib/systemd/system/multi-user.target.wants/docker.service
|
||||||
|
ln -sf ../log-forwarder.service $(TARGET_DIR)/usr/lib/systemd/system/multi-user.target.wants/log-forwarder.service
|
||||||
|
ln -sf ../computation-runner.service $(TARGET_DIR)/usr/lib/systemd/system/multi-user.target.wants/computation-runner.service
|
||||||
|
ln -sf ../egress-proxy.service $(TARGET_DIR)/usr/lib/systemd/system/multi-user.target.wants/egress-proxy.service
|
||||||
|
ln -sf ../cocos-agent.service $(TARGET_DIR)/usr/lib/systemd/system/multi-user.target.wants/cocos-agent.service
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(generic-package))
|
$(eval $(generic-package))
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
|
||||||
|
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
|
||||||
|
@@ -151,7 +151,15 @@
|
||||||
|
#include <linux/lp.h>
|
||||||
|
#include <linux/mroute.h>
|
||||||
|
#include <linux/mroute6.h>
|
||||||
|
-#include <linux/scc.h>
|
||||||
|
+#if defined(__has_include)
|
||||||
|
+# if __has_include(<linux/scc.h>)
|
||||||
|
+# include <linux/scc.h>
|
||||||
|
+# define SANITIZER_HAS_LINUX_SCC_H 1
|
||||||
|
+# endif
|
||||||
|
+#else
|
||||||
|
+# include <linux/scc.h>
|
||||||
|
+# define SANITIZER_HAS_LINUX_SCC_H 1
|
||||||
|
+#endif
|
||||||
|
#include <linux/serial.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
@@ -517,8 +525,13 @@
|
||||||
|
unsigned struct_kbsentry_sz = sizeof(struct kbsentry);
|
||||||
|
unsigned struct_mtconfiginfo_sz = sizeof(struct mtconfiginfo);
|
||||||
|
unsigned struct_nr_parms_struct_sz = sizeof(struct nr_parms_struct);
|
||||||
|
+#if SANITIZER_HAS_LINUX_SCC_H
|
||||||
|
unsigned struct_scc_modem_sz = sizeof(struct scc_modem);
|
||||||
|
unsigned struct_scc_stat_sz = sizeof(struct scc_stat);
|
||||||
|
+#else
|
||||||
|
+ unsigned struct_scc_modem_sz = 0;
|
||||||
|
+ unsigned struct_scc_stat_sz = 0;
|
||||||
|
+#endif
|
||||||
|
unsigned struct_serial_multiport_struct_sz
|
||||||
|
= sizeof(struct serial_multiport_struct);
|
||||||
|
unsigned struct_serial_struct_sz = sizeof(struct serial_struct);
|
||||||
@@ -1,6 +1,24 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
WORK_DIR="/cocos"
|
WORK_DIR="/cocos"
|
||||||
|
DOCKER_OVERRIDE_DIR="/etc/systemd/system/docker.service.d"
|
||||||
|
DOCKER_OVERRIDE_FILE="$DOCKER_OVERRIDE_DIR/override.conf"
|
||||||
|
|
||||||
|
# Docker runs on a writable bind mount while the rootfs itself stays ephemeral,
|
||||||
|
# so force RAM-disk mode to avoid pivot_root failures inside containers.
|
||||||
|
mkdir -p "$DOCKER_OVERRIDE_DIR"
|
||||||
|
if ! grep -qs '^Environment=DOCKER_RAMDISK=true$' "$DOCKER_OVERRIDE_FILE"; then
|
||||||
|
tee "$DOCKER_OVERRIDE_FILE" > /dev/null <<EOF
|
||||||
|
[Service]
|
||||||
|
Environment=DOCKER_RAMDISK=true
|
||||||
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Docker is required by the computation runner. Start the runtime stack here so
|
||||||
|
# later units don't depend on passive boot enablement or service ordering races.
|
||||||
|
systemctl start containerd.service
|
||||||
|
systemctl start docker.service
|
||||||
|
|
||||||
# IFACES are all network interfaces excluding lo (LOOPBACK) and sit interfaces
|
# IFACES are all network interfaces excluding lo (LOOPBACK) and sit interfaces
|
||||||
IFACES=$(ip link show | grep -vE 'LOOPBACK|sit*' | awk -F': ' '{print $2}')
|
IFACES=$(ip link show | grep -vE 'LOOPBACK|sit*' | awk -F': ' '{print $2}')
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
Description=Cocos AI agent
|
Description=Cocos AI agent
|
||||||
After=network.target attestation-service.service log-forwarder.service computation-runner.service egress-proxy.service
|
After=network.target attestation-service.service log-forwarder.service computation-runner.service egress-proxy.service
|
||||||
Requires=log-forwarder.service computation-runner.service egress-proxy.service
|
Requires=log-forwarder.service computation-runner.service egress-proxy.service
|
||||||
Before=docker.service
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
WorkingDirectory=/cocos
|
WorkingDirectory=/cocos
|
||||||
@@ -17,4 +16,4 @@ Restart=always
|
|||||||
RestartSec=5s
|
RestartSec=5s
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Cocos AI Computation Runner
|
Description=Cocos AI Computation Runner
|
||||||
After=network.target log-forwarder.service
|
After=network.target log-forwarder.service docker.service
|
||||||
Before=cocos-agent.service
|
Before=cocos-agent.service
|
||||||
Requires=log-forwarder.service
|
Requires=log-forwarder.service
|
||||||
|
Wants=docker.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
WorkingDirectory=/cocos
|
WorkingDirectory=/cocos
|
||||||
@@ -17,4 +18,4 @@ Restart=always
|
|||||||
RestartSec=5s
|
RestartSec=5s
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ Restart=always
|
|||||||
RestartSec=5s
|
RestartSec=5s
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: internal/proto/attestation-agent/attestation-agent.proto
|
// source: internal/proto/attestation-agent/attestation-agent.proto
|
||||||
|
|
||||||
package attestation_agent
|
package attestation_agent
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v7.35.0
|
// - protoc v7.35.1
|
||||||
// source: internal/proto/attestation-agent/attestation-agent.proto
|
// source: internal/proto/attestation-agent/attestation-agent.proto
|
||||||
|
|
||||||
package attestation_agent
|
package attestation_agent
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: internal/proto/attestation/v1/attestation.proto
|
// source: internal/proto/attestation/v1/attestation.proto
|
||||||
|
|
||||||
package attestation
|
package attestation
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v7.35.0
|
// - protoc v7.35.1
|
||||||
// source: internal/proto/attestation/v1/attestation.proto
|
// source: internal/proto/attestation/v1/attestation.proto
|
||||||
|
|
||||||
package attestation
|
package attestation
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.35.0
|
// protoc v7.35.1
|
||||||
// source: manager/manager.proto
|
// source: manager/manager.proto
|
||||||
|
|
||||||
package manager
|
package manager
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v7.35.0
|
// - protoc v7.35.1
|
||||||
// source: manager/manager.proto
|
// source: manager/manager.proto
|
||||||
|
|
||||||
package manager
|
package manager
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/absmach/certs/sdk"
|
|
||||||
"github.com/ultravioletrs/cocos/pkg/atls/ea"
|
"github.com/ultravioletrs/cocos/pkg/atls/ea"
|
||||||
eaattestation "github.com/ultravioletrs/cocos/pkg/atls/eaattestation"
|
eaattestation "github.com/ultravioletrs/cocos/pkg/atls/eaattestation"
|
||||||
cocosattestation "github.com/ultravioletrs/cocos/pkg/attestation"
|
cocosattestation "github.com/ultravioletrs/cocos/pkg/attestation"
|
||||||
@@ -30,7 +29,7 @@ type provider struct {
|
|||||||
platformType cocosattestation.PlatformType
|
platformType cocosattestation.PlatformType
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProvider(attClient attestationclient.Client, platformType cocosattestation.PlatformType, _ string, _ string, _ sdk.SDK) (CertificateProvider, error) {
|
func NewProvider(attClient attestationclient.Client, platformType cocosattestation.PlatformType) (CertificateProvider, error) {
|
||||||
if attClient == nil {
|
if attClient == nil {
|
||||||
return nil, fmt.Errorf("atls: missing attestation client")
|
return nil, fmt.Errorf("atls: missing attestation client")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user