Update public bundle metadata contract

This commit is contained in:
Michel Paulissen 2026-07-04 10:22:53 +02:00
parent c4d8d94f49
commit c4141e0dee
6 changed files with 204 additions and 5 deletions

View file

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use crate::{Digest, EnvironmentResource};
use crate::{Digest, EnvironmentResource, SourceTransferPolicy};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SelectedInput {
@ -12,19 +12,49 @@ pub struct SelectedInput {
pub struct BundleIdentityInputs {
pub wasm_code: Digest,
pub task_abi: Digest,
pub entrypoints: Vec<String>,
pub default_entrypoint: String,
pub environments: Vec<EnvironmentResource>,
pub source_provider_manifest: Digest,
pub source_transfer_policy: SourceTransferPolicy,
pub selected_inputs: Vec<SelectedInput>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BundleMetadata {
pub identity: Digest,
pub wasm_code: Digest,
pub task_metadata: BundleTaskMetadata,
pub source_metadata: BundleSourceMetadata,
pub debug_metadata: BundleDebugMetadata,
pub environments: Vec<EnvironmentResource>,
pub selected_inputs: Vec<SelectedInput>,
pub embeds_full_container_images: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BundleTaskMetadata {
pub task_abi: Digest,
pub entrypoints: Vec<String>,
pub default_entrypoint: String,
pub boundary: String,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BundleSourceMetadata {
pub source_provider_manifest: Digest,
pub transfer_policy: SourceTransferPolicy,
pub selected_inputs: Vec<SelectedInput>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BundleDebugMetadata {
pub available: bool,
pub source_level_breakpoints: bool,
pub dap_virtual_process: bool,
pub variables_pane_supported: bool,
}
impl BundleIdentityInputs {
pub fn identity(&self) -> Digest {
let mut parts = vec![
@ -32,8 +62,16 @@ impl BundleIdentityInputs {
self.wasm_code.as_str().as_bytes().to_vec(),
self.task_abi.as_str().as_bytes().to_vec(),
self.source_provider_manifest.as_str().as_bytes().to_vec(),
self.default_entrypoint.as_bytes().to_vec(),
format!("{:?}", self.source_transfer_policy).into_bytes(),
];
let mut entrypoints = self.entrypoints.clone();
entrypoints.sort();
for entrypoint in entrypoints {
parts.push(entrypoint.into_bytes());
}
let mut environments = self.environments.clone();
environments.sort_by(|left, right| left.name.cmp(&right.name));
for environment in environments {
@ -53,8 +91,29 @@ impl BundleIdentityInputs {
}
pub fn inspectable_metadata(&self) -> BundleMetadata {
let mut entrypoints = self.entrypoints.clone();
entrypoints.sort();
BundleMetadata {
identity: self.identity(),
wasm_code: self.wasm_code.clone(),
task_metadata: BundleTaskMetadata {
task_abi: self.task_abi.clone(),
entrypoints,
default_entrypoint: self.default_entrypoint.clone(),
boundary: "disasmer_task_exports".to_owned(),
},
source_metadata: BundleSourceMetadata {
source_provider_manifest: self.source_provider_manifest.clone(),
transfer_policy: self.source_transfer_policy.clone(),
selected_inputs: self.selected_inputs.clone(),
},
debug_metadata: BundleDebugMetadata {
available: true,
source_level_breakpoints: true,
dap_virtual_process: true,
variables_pane_supported: true,
},
environments: self.environments.clone(),
selected_inputs: self.selected_inputs.clone(),
embeds_full_container_images: false,
@ -86,8 +145,11 @@ mod tests {
let base = BundleIdentityInputs {
wasm_code: Digest::sha256("wasm"),
task_abi: Digest::sha256("abi"),
entrypoints: vec!["build".to_owned()],
default_entrypoint: "build".to_owned(),
environments: vec![env("recipe-a")],
source_provider_manifest: Digest::sha256("source"),
source_transfer_policy: SourceTransferPolicy::local_first_snapshot_chunks(),
selected_inputs: vec![],
};
let mut changed = base.clone();
@ -101,8 +163,11 @@ mod tests {
let inputs = BundleIdentityInputs {
wasm_code: Digest::sha256("wasm"),
task_abi: Digest::sha256("abi"),
entrypoints: vec!["build".to_owned(), "test".to_owned()],
default_entrypoint: "build".to_owned(),
environments: vec![env("recipe")],
source_provider_manifest: Digest::sha256("source"),
source_transfer_policy: SourceTransferPolicy::local_first_snapshot_chunks(),
selected_inputs: vec![SelectedInput {
path: "inputs/config.json".to_owned(),
digest: Digest::sha256("config"),
@ -111,6 +176,19 @@ mod tests {
let metadata = inputs.inspectable_metadata();
assert!(metadata.wasm_code.as_str().starts_with("sha256:"));
assert_eq!(metadata.task_metadata.default_entrypoint, "build");
assert!(metadata
.task_metadata
.entrypoints
.contains(&"test".to_owned()));
assert!(metadata.debug_metadata.dap_virtual_process);
assert!(
metadata
.source_metadata
.transfer_policy
.local_source_bytes_remain_node_local
);
assert_eq!(metadata.environments.len(), 1);
assert!(!metadata.embeds_full_container_images);
}

View file

@ -26,7 +26,10 @@ pub use auth::{
CliLoginFlow, CredentialKind, EnrollmentError, EnrollmentGrant, IdentityKind, NodeCredential,
PublicKeyIdentity, Scope,
};
pub use bundle::{BundleIdentityInputs, BundleMetadata, SelectedInput};
pub use bundle::{
BundleDebugMetadata, BundleIdentityInputs, BundleMetadata, BundleSourceMetadata,
BundleTaskMetadata, SelectedInput,
};
pub use capability::{Capability, CapabilityReportError, EnvironmentBackend, NodeCapabilities, Os};
pub use checkpoint::{
CheckpointBoundary, CompatibilityFailure, RestartDecision, RestartPolicy, RestartRequest,