Add SandboxBuilder - #1725
Conversation
`SandboxBuilder` is the entry point for creating a sandbox. It gathers machine configuration, host functions, init data and memory mappings, then builds a `MultiUseSandbox` from a guest binary on disk, a guest binary in memory, or a snapshot. It merges the roles of `SandboxConfiguration`, `GuestEnvironment` and `UninitializedSandbox` into a single type, so all three can become implementation details. Every setting has an in place accessor taking `&mut self` and a `with_*` counterpart consuming `self` for chaining. Machine configuration values are readable through `get_*`. `map_memory_region` is `unsafe`, matching `MultiUseSandbox::map_region`. The mapped region must stay valid for the lifetime of the built sandbox. `build_from_snapshot` errors when `init_data` or `max_guest_log_level` are set, as a snapshot already carries both. Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new SandboxBuilder API in hyperlight_host as the primary entry point for configuring and constructing MultiUseSandbox instances from a guest binary (file or bytes) or from a snapshot, consolidating configuration, host-function registration, init data, and memory mappings into one builder type.
Changes:
- Added
sandbox::builder::SandboxBuilderwithbuild_from_file,build_from_bytes, andbuild_from_snapshotconstructors pluswith_*/in-place setters. - Exposed
MultiUseSandbox::builder()and re-exportedSandboxBuilderfromhyperlight_host. - Adjusted host function registry internals to support builder-driven registration.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/hyperlight_host/src/sandbox/mod.rs | Exposes the new builder module under sandbox. |
| src/hyperlight_host/src/sandbox/initialized_multi_use.rs | Adds MultiUseSandbox::builder() entry point returning a default SandboxBuilder. |
| src/hyperlight_host/src/sandbox/host_funcs.rs | Loosens visibility of FunctionRegistry::functions_map to support builder registration. |
| src/hyperlight_host/src/sandbox/builder.rs | New builder implementation + unit tests for building from file/bytes/snapshot. |
| src/hyperlight_host/src/lib.rs | Re-exports SandboxBuilder from the crate root. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| } | ||
|
|
||
| impl SandboxBuilder { | ||
| /// Create a builder with the default configuration and no host functions. |
There was a problem hiding this comment.
HostPrint is always available, this is the same as the existing behaviour.
There was a problem hiding this comment.
true, but maybe we can word it something like ".. and no additional host functions" to avoid confusion?
I like that this just simplifies the API, and would be an almost drop in for https://github.com/hyperlight-dev/hyperlight-sandbox which I would be able to reduce the code there. What do propose for plans to depreciate the older apis? I think this would provide a bit more flexibility to do things internally |
|
I should have dropped this link in the PR description. At the end of the document I added how we can deprecate the old API We have 3 deprecation levels, in increasing severity:
Applying I'd be happy to hear different opinions. |
ludfjig
left a comment
There was a problem hiding this comment.
I like this! Only one concern:
- Looks like pr is missing newly added
guest_msrsconfig.
Some minor things:
- Would it be possible to somehow allow multiple sandboxes to be created from a builder? Or have builder be clonable? Just thinking about ergonomics if multiple identical sandboxes are to be created (I understand this might not be easy with host functions...)
- Also bikeshedding if any apis should be renamed (my candiadates are
max_guest_log_level,map_file_cow,map_memory_region) but not blocking for this pr... - Could you add this builder addition to CHANGELOG.md?
- Do we want to consider adding the possiblity of having sandboxes without any host functions (including no hostprint?)
| /// Builds a [`Sandbox`]. | ||
| /// | ||
| /// Start from [`SandboxBuilder::new`], adjust settings through the `with_*` | ||
| /// (consuming, chainable) or bare-named (in place) accessors, then call one of | ||
| /// the `build_from_*` methods to create the sandbox from a guest binary on | ||
| /// disk, a guest binary in memory, or a [`Snapshot`]. Every setting has a | ||
| /// default, so a builder with no adjustments is valid. | ||
| #[derive(Default)] | ||
| pub struct SandboxBuilder { |
There was a problem hiding this comment.
Maybe a rustdoc example showing off relevant apis could be a good addition
| } | ||
|
|
||
| /// Like [`Self::max_guest_log_level`], but consumes and returns `self` for chaining. | ||
| pub fn with_max_guest_log_level(mut self, level: LevelFilter) -> Self { |
There was a problem hiding this comment.
thinking about if we can name this something better...
| let host_funcs = self.host_funcs.into_inner().functions_map; | ||
| for (func_name, func_entry) in host_funcs { | ||
| func_registry.register_host_function(func_name, func_entry); | ||
| } |
There was a problem hiding this comment.
this will re-register default hostprint host function (which is probably fine...?)
Description
SandboxBuilderis the entry point for creating a sandbox. It gathers machine configuration, host functions, init data and memory mappings, then builds aMultiUseSandboxfrom a guest binary on disk, a guest binary in memory, or a snapshot.It merges the roles of
SandboxConfiguration,GuestEnvironmentandUninitializedSandboxinto a single type, so all three can become implementation details.Every setting has an in place accessor taking
&mut selfand awith_*counterpart consumingselffor chaining. Machine configuration values are readable throughget_*.map_memory_regionisunsafe, matchingMultiUseSandbox::map_region. The mapped region must stay valid for the lifetime of the built sandbox.build_from_snapshoterrors wheninit_dataormax_guest_log_levelare set, as a snapshot already carries both.Scope
This PR only adds the new API, it does not deprecate any old API, and does not replace the use of the old API throughout the repo.