feat: persist and transfer script command payloads
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
|
||||
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
|
||||
"github.com/rvbox/rvbox/internal/agentproto"
|
||||
"github.com/rvbox/rvbox/internal/client/spool"
|
||||
"github.com/rvbox/rvbox/internal/domain"
|
||||
)
|
||||
|
||||
var ErrInvalidScriptTransfer = errors.New("invalid script transfer")
|
||||
|
||||
// ApplyScriptChunk validates one server script frame and appends it to the
|
||||
// durable client spool. The spool accepts only the next contiguous range or
|
||||
// an exact replay, so reconnects cannot create holes or duplicate bytes.
|
||||
func ApplyScriptChunk(ctx context.Context, store *spool.Store, session Session, chunk *rvboxv1.ScriptChunk, limits agentproto.Limits) (spool.ScriptStatus, error) {
|
||||
if store == nil || session.Generation == 0 || chunk == nil || chunk.GetOffset() > limits.MaxScriptBytes || uint64(len(chunk.GetData())) > limits.MaxRawChunkBytes || len(chunk.GetSha256()) != sha256.Size {
|
||||
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
||||
}
|
||||
issue, err := domain.ParseUUIDv7(chunk.GetIssueUuid())
|
||||
if err != nil || sha256.Sum256(chunk.GetData()) != bytesToDigest(chunk.GetSha256()) {
|
||||
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
||||
}
|
||||
return store.AppendScriptChunk(ctx, issue, chunk.GetOffset(), chunk.GetData(), bytesToDigest(chunk.GetSha256()))
|
||||
}
|
||||
|
||||
// ApplyScriptCommit marks a fully received script launch-eligible only after
|
||||
// the spool verifies the declared size and whole-body SHA-256.
|
||||
func ApplyScriptCommit(ctx context.Context, store *spool.Store, session Session, commit *rvboxv1.ScriptCommit, limits agentproto.Limits) (spool.ScriptStatus, error) {
|
||||
if store == nil || session.Generation == 0 || commit == nil || commit.GetSizeBytes() > limits.MaxScriptBytes || len(commit.GetSha256()) != sha256.Size {
|
||||
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
||||
}
|
||||
issue, err := domain.ParseUUIDv7(commit.GetIssueUuid())
|
||||
if err != nil {
|
||||
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
||||
}
|
||||
return store.CommitScript(ctx, issue, spool.ScriptDescriptor{SizeBytes: commit.GetSizeBytes(), SHA256: bytesToDigest(commit.GetSha256())})
|
||||
}
|
||||
|
||||
func bytesToDigest(value []byte) [sha256.Size]byte {
|
||||
var digest [sha256.Size]byte
|
||||
copy(digest[:], value)
|
||||
return digest
|
||||
}
|
||||
Reference in New Issue
Block a user