Sync public tree to 4a860d7

This commit is contained in:
Michel Paulissen 2026-07-04 13:26:01 +02:00
parent 1dad0df5c4
commit 4f5df7da20
4 changed files with 236 additions and 5 deletions

View file

@ -1,4 +1,4 @@
use std::collections::BTreeSet;
use std::collections::{BTreeMap, BTreeSet};
use std::io::{BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream, ToSocketAddrs};
use std::path::{Path, PathBuf};
@ -10,8 +10,9 @@ use base64::{engine::general_purpose::STANDARD as BASE64_STANDARD, Engine as _};
use clap::{Args, Parser, Subcommand};
use disasmer_core::{
diagnose_environment_references, BrowserLoginFlow, BundleIdentityInputs, BundleMetadata,
Capability, CliLoginFlow, Digest, EnvironmentReference, LimitKind, NodeCapabilities,
ProjectModel, ResourceLimits, SelectedInput, SourceProviderKind, SourceProviderManifest,
Capability, CliLoginFlow, Digest, EnvironmentBackend, EnvironmentReference, LimitKind,
NodeCapabilities, ProjectModel, ResourceLimits, SelectedInput, SourceProviderKind,
SourceProviderManifest,
};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
@ -678,6 +679,7 @@ struct NodeAttachPlan {
node: String,
coordinator: Option<String>,
capabilities: NodeCapabilities,
detection: NodeAttachDetectionEvidence,
grant_disclosures: Vec<CapabilityGrantDisclosure>,
enrollment: Option<NodeEnrollmentPlan>,
}
@ -711,6 +713,32 @@ struct CapabilityGrantDisclosure {
coordinator_policy_limited: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
struct NodeAttachDetectionEvidence {
auto_detected: bool,
os: disasmer_core::Os,
arch: String,
command_backend: String,
command_backend_available: bool,
container_backend: Option<String>,
container_backend_reported: bool,
container_backend_available: bool,
source_provider_backends: Vec<SourceProviderBackendStatus>,
manual_capability_overrides_allowed: bool,
manual_capability_overrides: Vec<String>,
recognized_capability_overrides: Vec<Capability>,
unrecognized_capability_overrides: Vec<String>,
os_arch_capabilities_require_manual_flags: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
struct SourceProviderBackendStatus {
provider: String,
detected: bool,
available: bool,
reason: String,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
struct NodeEnrollmentPlan {
grant: String,
@ -2794,6 +2822,12 @@ fn human_report(value: &Value) -> String {
}
}
}
if let Some(detection) = value
.pointer("/plan/detection")
.or_else(|| value.get("detection"))
{
push_node_attach_detection(&mut lines, detection);
}
if let Some(disclosures) = value
.get("grant_disclosures")
.and_then(Value::as_array)
@ -2825,6 +2859,64 @@ fn human_report(value: &Value) -> String {
lines.join("\n")
}
fn push_node_attach_detection(lines: &mut Vec<String>, detection: &Value) {
push_nested_string_field(lines, detection, "os", "node os");
push_nested_string_field(lines, detection, "arch", "node arch");
push_nested_string_field(lines, detection, "command_backend", "command backend");
if let Some(backend) = detection.get("container_backend").and_then(Value::as_str) {
let available = detection
.get("container_backend_available")
.and_then(Value::as_bool)
.unwrap_or(false);
lines.push(format!(
"container backend: {backend} ({})",
if available { "available" } else { "reported" }
));
} else if detection
.get("container_backend_reported")
.and_then(Value::as_bool)
.unwrap_or(false)
{
lines.push("container backend: reported".to_owned());
}
if let Some(providers) = detection
.get("source_provider_backends")
.and_then(Value::as_array)
{
let entries = providers
.iter()
.filter_map(|provider| {
let name = provider.get("provider").and_then(Value::as_str)?;
let state = if provider
.get("available")
.and_then(Value::as_bool)
.unwrap_or(false)
{
"available"
} else {
"detected"
};
Some(format!("{name}={state}"))
})
.collect::<Vec<_>>();
if !entries.is_empty() {
lines.push(format!("source providers: {}", entries.join(", ")));
}
}
if let Some(overrides) = detection
.get("manual_capability_overrides")
.and_then(Value::as_array)
{
let overrides = overrides
.iter()
.filter_map(Value::as_str)
.collect::<Vec<_>>();
if !overrides.is_empty() {
lines.push(format!("capability overrides: {}", overrides.join(", ")));
}
}
}
fn push_string_field(lines: &mut Vec<String>, value: &Value, key: &str, label: &str) {
if let Some(text) = value.get(key).and_then(Value::as_str) {
lines.push(format!("{label}: {text}"));
@ -5748,11 +5840,18 @@ fn add_workflow_actor_fields(request: &mut Value, session: &CliSession, fallback
fn attach_plan(args: AttachArgs) -> NodeAttachPlan {
let mut capabilities = NodeCapabilities::detect_current();
let mut recognized_capability_overrides = Vec::new();
let mut unrecognized_capability_overrides = Vec::new();
for cap in &args.caps {
if let Some(parsed) = parse_capability(&cap) {
recognized_capability_overrides.push(parsed.clone());
capabilities.capabilities.insert(parsed);
} else {
unrecognized_capability_overrides.push(cap.clone());
}
}
recognized_capability_overrides.sort();
recognized_capability_overrides.dedup();
let node = args.node.unwrap_or_else(default_node_id);
let public_key = args
.public_key
@ -5762,17 +5861,94 @@ fn attach_plan(args: AttachArgs) -> NodeAttachPlan {
public_key_fingerprint: Digest::sha256(public_key),
exchanges_short_lived_grant_for_long_lived_node_identity: true,
});
let detection = node_attach_detection_evidence(
&capabilities,
args.caps,
recognized_capability_overrides,
unrecognized_capability_overrides,
);
let grant_disclosures = capability_grant_disclosures(&capabilities);
NodeAttachPlan {
node,
coordinator: args.coordinator,
capabilities,
detection,
grant_disclosures,
enrollment,
}
}
fn node_attach_detection_evidence(
capabilities: &NodeCapabilities,
manual_capability_overrides: Vec<String>,
recognized_capability_overrides: Vec<Capability>,
unrecognized_capability_overrides: Vec<String>,
) -> NodeAttachDetectionEvidence {
let command_backend_available = capabilities.capabilities.contains(&Capability::Command);
let container_backend_reported = capabilities
.environment_backends
.contains(&EnvironmentBackend::Container);
let container_backend = container_backend_reported.then(|| "rootless-podman".to_owned());
let container_backend_available = container_backend_reported
&& capabilities
.capabilities
.contains(&Capability::RootlessPodman)
&& command_available("podman");
NodeAttachDetectionEvidence {
auto_detected: true,
os: capabilities.os.clone(),
arch: capabilities.arch.clone(),
command_backend: if command_backend_available {
"native-command".to_owned()
} else {
"unavailable".to_owned()
},
command_backend_available,
container_backend,
container_backend_reported,
container_backend_available,
source_provider_backends: source_provider_backend_statuses(capabilities),
manual_capability_overrides_allowed: true,
manual_capability_overrides,
recognized_capability_overrides,
unrecognized_capability_overrides,
os_arch_capabilities_require_manual_flags: false,
}
}
fn source_provider_backend_statuses(
capabilities: &NodeCapabilities,
) -> Vec<SourceProviderBackendStatus> {
let mut statuses = BTreeMap::new();
for provider in &capabilities.source_providers {
let available = match provider.as_str() {
"filesystem" => capabilities
.capabilities
.contains(&Capability::SourceFilesystem),
"git" => command_available("git"),
_ => true,
};
statuses.insert(
provider.clone(),
SourceProviderBackendStatus {
provider: provider.clone(),
detected: true,
available,
reason: if available {
"detected by local node capability probe".to_owned()
} else {
format!(
"source provider `{provider}` was detected but its local helper is missing"
)
},
},
);
}
statuses.into_values().collect()
}
fn capability_grant_disclosures(capabilities: &NodeCapabilities) -> Vec<CapabilityGrantDisclosure> {
let mut disclosures = Vec::new();
let mut push = |capability: Capability, grant: &str, description: &str, risk: &str| {
@ -6225,6 +6401,27 @@ mod tests {
.capabilities
.contains(&Capability::QuicDirect));
assert!(!plan.capabilities.arch.is_empty());
assert!(plan.detection.auto_detected);
assert_eq!(plan.detection.os, plan.capabilities.os);
assert_eq!(plan.detection.arch, plan.capabilities.arch);
assert_eq!(plan.detection.command_backend, "native-command");
assert!(plan.detection.command_backend_available);
assert!(plan.detection.manual_capability_overrides_allowed);
assert_eq!(
plan.detection.manual_capability_overrides,
vec!["quic-direct".to_owned()]
);
assert!(plan
.detection
.recognized_capability_overrides
.contains(&Capability::QuicDirect));
assert!(plan.detection.unrecognized_capability_overrides.is_empty());
assert!(!plan.detection.os_arch_capabilities_require_manual_flags);
assert!(plan
.detection
.source_provider_backends
.iter()
.any(|provider| provider.provider == "filesystem" && provider.detected));
}
#[test]