feat(httpapi): harden control plane and speed up prefix refresh
Очередь job получила lease и fencing, телеметрия и прогресс deploy сохраняются, ревизия пишет manifest входов. Обновление префиксов не переписывает неизменённый снимок, большие наборы идут через COPY, а устаревшая ревизия не попадает в deploy. Бандл ноды кэшируется, prune и постановка job больше не держат горячий путь. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
924f111e48
commit
f8e0520817
197 files changed
+18655
-1416
No files matched your search
+35
-8
@@ -9,7 +9,6 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -36,22 +35,47 @@ const manifestName = "manifest.json"
|
||||
|
||||
// BuildGzippedTar builds a .tar.gz with manifest.json, bundle.sig (Ed25519 over manifest JSON), and payload files.
|
||||
func BuildGzippedTar(revisionID, speakerID string, fragments map[string]string, priv ed25519.PrivateKey) ([]byte, error) {
|
||||
return BuildGzippedTarWithLimits(revisionID, speakerID, fragments, priv, Limits{})
|
||||
}
|
||||
|
||||
// BuildGzippedTarWithLimits preserves the manifest/signature wire format while
|
||||
// refusing payloads that exceed the receiving node's configured budgets.
|
||||
func BuildGzippedTarWithLimits(revisionID, speakerID string, fragments map[string]string, priv ed25519.PrivateKey, limits Limits) ([]byte, error) {
|
||||
l, err := limits.Normalized()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(priv) != ed25519.PrivateKeySize {
|
||||
return nil, fmt.Errorf("bundle: invalid ed25519 private key size")
|
||||
}
|
||||
pub := priv.Public().(ed25519.PublicKey)
|
||||
|
||||
norm := make(map[string]string, len(fragments))
|
||||
norm := make(map[string]string)
|
||||
seen := map[string]bool{}
|
||||
var total int64
|
||||
for p, content := range fragments {
|
||||
p = path.Clean(strings.TrimPrefix(p, "/"))
|
||||
if p == "." || strings.HasPrefix(p, "..") {
|
||||
return nil, fmt.Errorf("bundle: invalid path %q", p)
|
||||
}
|
||||
if strings.HasPrefix(p, "_") {
|
||||
continue // UI-only preview aggregate, not shipped to nodes
|
||||
}
|
||||
if len(norm) >= l.MaxEntries-2 {
|
||||
return nil, ErrLimit
|
||||
}
|
||||
if err := validatePath(p, l.MaxPathBytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p == manifestName || p == sigFileName || seen[strings.ToLower(p)] {
|
||||
return nil, fmt.Errorf("bundle: duplicate or reserved path %q", p)
|
||||
}
|
||||
seen[strings.ToLower(p)] = true
|
||||
if int64(len(content)) > l.MaxFileBytes || int64(len(content)) > l.MaxExpandedBytes-total {
|
||||
return nil, ErrLimit
|
||||
}
|
||||
total += int64(len(content))
|
||||
norm[p] = content
|
||||
}
|
||||
if len(norm) > l.MaxEntries-2 {
|
||||
return nil, ErrLimit
|
||||
}
|
||||
|
||||
var files []FileEntry
|
||||
var payload [][]byte
|
||||
@@ -75,11 +99,14 @@ func BuildGzippedTar(revisionID, speakerID string, fragments map[string]string,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if int64(len(manifestJSON)) > l.MaxManifestBytes {
|
||||
return nil, ErrLimit
|
||||
}
|
||||
sig := ed25519.Sign(priv, manifestJSON)
|
||||
|
||||
var buf bytes.Buffer
|
||||
gw := gzip.NewWriter(&buf)
|
||||
tw := tar.NewWriter(gw)
|
||||
gw := gzip.NewWriter(&limitedWriter{w: &buf, remaining: l.MaxCompressedBytes})
|
||||
tw := tar.NewWriter(&limitedWriter{w: gw, remaining: l.MaxExpandedBytes})
|
||||
|
||||
add := func(name string, body []byte) error {
|
||||
hdr := &tar.Header{
|
||||
|
||||
Reference in new issue
Block a user