-
Notifications
You must be signed in to change notification settings - Fork 64
Add 0.8 one-shot configuration contract #909
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Gudge (MGudgin)
merged 1 commit into
main
from
user/gudge/version_specific_config_parsers_phase5a
Aug 19, 2026
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use super::primitives::OptionalField; | ||
| use std::num::NonZeroU16; | ||
|
|
||
| /// Placeholder feature used to exercise experimental configuration plumbing. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct TestFeature { | ||
| /// The message for the test feature. | ||
| #[serde(default)] | ||
| pub message: OptionalField<String>, | ||
| } | ||
|
|
||
| /// One-shot telemetry override. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct Telemetry { | ||
| /// Whether telemetry is enabled. | ||
| #[serde(default)] | ||
| pub enabled: OptionalField<bool>, | ||
| } | ||
|
|
||
| /// Compatibility settings accepted for one-shot Windows Sandbox requests. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct OneShotWindowsSandbox { | ||
| /// Idle timeout before teardown, in milliseconds. | ||
| #[serde(default)] | ||
| pub idle_timeout_ms: OptionalField<u32>, | ||
| /// Legacy idle-timeout field retained for compatibility. | ||
| #[serde(default)] | ||
| pub idle_timeout: OptionalField<u32>, | ||
| /// Optional daemon named-pipe override. | ||
| #[serde(default)] | ||
| pub daemon_pipe_name: OptionalField<String>, | ||
| } | ||
|
|
||
| #[rustfmt::skip] | ||
| string_enum! { | ||
| /// Transport protocol for a WSLC port mapping. | ||
| #[derive(Debug)] | ||
| pub enum TransportProtocol { | ||
| /// TCP transport. | ||
| Tcp => ["tcp"], | ||
| } | ||
| } | ||
|
|
||
| /// A host-to-container WSLC port mapping. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct PortMapping { | ||
| /// Non-zero TCP port on the Windows host. | ||
| pub windows_port: NonZeroU16, | ||
| /// Non-zero TCP port inside the container. | ||
| pub container_port: NonZeroU16, | ||
| /// Optional transport protocol. Only TCP is currently supported. | ||
| #[serde(default)] | ||
| pub protocol: OptionalField<TransportProtocol>, | ||
| } | ||
|
|
||
| /// One-shot WSLC backend settings. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct OneShotWslc { | ||
| /// Target operating system inside the container. | ||
| #[serde(default)] | ||
| pub target_os: OptionalField<String>, | ||
| /// Container image reference. | ||
| #[serde(default)] | ||
| pub image: OptionalField<String>, | ||
| /// Path to a local image tarball to import. | ||
| #[serde(default)] | ||
| pub image_tar_path: OptionalField<String>, | ||
| /// Requested virtual CPU count. | ||
| #[serde(default)] | ||
| pub cpu_count: OptionalField<u32>, | ||
| /// Requested memory limit in megabytes. | ||
| #[serde(default)] | ||
| pub memory_mb: OptionalField<u64>, | ||
| /// Whether GPU passthrough is enabled. | ||
| #[serde(default)] | ||
| pub gpu: OptionalField<bool>, | ||
| /// Optional storage path override. | ||
| #[serde(default)] | ||
| pub storage_path: OptionalField<String>, | ||
| /// Optional host-to-container TCP port mappings. | ||
| #[serde(default)] | ||
| pub port_mappings: OptionalField<Vec<PortMapping>>, | ||
| } | ||
|
|
||
| /// Experimental settings. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct OneShotExperimental { | ||
| /// Optional placeholder test feature. | ||
| #[serde(default)] | ||
| pub test: OptionalField<TestFeature>, | ||
| /// Optional one-shot Windows Sandbox compatibility settings. | ||
| #[serde(rename = "windows_sandbox", default)] | ||
| pub windows_sandbox: OptionalField<OneShotWindowsSandbox>, | ||
| /// Optional one-shot WSLC backend settings. | ||
| #[serde(default)] | ||
| pub wslc: OptionalField<OneShotWslc>, | ||
| /// Optional telemetry override. | ||
| #[serde(default)] | ||
| pub telemetry: OptionalField<Telemetry>, | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| //! Wire types for the mutable `0.8.0-alpha` configuration contract. | ||
| //! | ||
| //! These types validate the JSON structure and value constraints of the | ||
| //! in-development contract. They preserve omitted optional fields for a later | ||
| //! adapter to default and normalize. | ||
|
|
||
| // Serde's default fieldless-enum deserializer also accepts externally | ||
| // tagged object forms such as {"process": null}. Published contracts accept | ||
| // only string values. This macro generates a string-only deserializer while | ||
| // supporting explicit compatibility aliases. | ||
| macro_rules! string_enum { | ||
| ( | ||
| $(#[$enum_meta:meta])* | ||
| $vis:vis enum $name:ident { | ||
| $( | ||
| $(#[$variant_meta:meta])* | ||
| $variant:ident => [ | ||
| $canonical:literal | ||
| $(, $alias:literal)* | ||
| ] | ||
| ),+ $(,)? | ||
| } | ||
| ) => { | ||
| $(#[$enum_meta])* | ||
| $vis enum $name { | ||
| $( | ||
| $(#[$variant_meta])* | ||
| $variant, | ||
| )+ | ||
| } | ||
|
|
||
| impl $name { | ||
| const WIRE_VALUES: &'static [&'static str] = &[ | ||
|
MGudgin marked this conversation as resolved.
|
||
| $( | ||
| $canonical, | ||
| $($alias,)* | ||
| )+ | ||
| ]; | ||
| } | ||
|
|
||
| impl<'de> serde::Deserialize<'de> for $name { | ||
| fn deserialize<D>( | ||
| deserializer: D, | ||
| ) -> Result<Self, D::Error> | ||
| where | ||
| D: serde::Deserializer<'de>, | ||
| { | ||
| struct StringEnumVisitor; | ||
|
|
||
| impl<'de> serde::de::Visitor<'de> | ||
| for StringEnumVisitor | ||
| { | ||
| type Value = $name; | ||
|
|
||
| fn expecting( | ||
| &self, | ||
| formatter: &mut std::fmt::Formatter<'_>, | ||
| ) -> std::fmt::Result { | ||
| write!( | ||
| formatter, | ||
| "a valid {} string", | ||
| stringify!($name) | ||
| ) | ||
| } | ||
|
|
||
| fn visit_str<E>( | ||
| self, | ||
| value: &str, | ||
| ) -> Result<Self::Value, E> | ||
| where | ||
| E: serde::de::Error, | ||
| { | ||
| match value { | ||
| $( | ||
| $canonical | ||
| $(| $alias)* | ||
| => Ok($name::$variant), | ||
| )+ | ||
| _ => Err(E::unknown_variant( | ||
| value, | ||
| $name::WIRE_VALUES, | ||
| )), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| deserializer.deserialize_str(StringEnumVisitor) | ||
| } | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| #[rustfmt::skip] | ||
| string_enum! { | ||
| /// The exact version marker accepted by this contract. | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| pub enum Version { | ||
| /// The development `0.8.0-alpha` contract. | ||
| V0_8_0Alpha => ["0.8.0-alpha"], | ||
| } | ||
| } | ||
|
|
||
| /// The development `0.8.0-alpha` configuration contract. | ||
| mod experimental; | ||
| mod network; | ||
| mod one_shot; | ||
| mod primitives; | ||
| mod stable; | ||
|
|
||
| pub use experimental::{ | ||
| OneShotExperimental, OneShotWindowsSandbox, OneShotWslc, PortMapping, Telemetry, TestFeature, | ||
| TransportProtocol, | ||
| }; | ||
| pub use network::{DefaultNetworkPolicy, Network, NetworkEnforcementMode, NetworkProxy}; | ||
| pub use one_shot::{Containment as OneShotContainment, Request as OneShotRequest}; | ||
| pub use primitives::{NonEmptyString, OptionalField, True}; | ||
| pub use stable::{ | ||
| CaptureDenials, CaptureDenialsMode, Fallback, Filesystem, LaunchMethod, Lifecycle, Lxc, | ||
| Process, ProcessContainer, ProcessContainerUi, ProcessContainerUiIsolation, Seatbelt, Ui, | ||
| UiClipboard, | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use std::num::NonZeroU16; | ||
|
|
||
| use super::primitives::{OptionalField, True}; | ||
|
|
||
| #[rustfmt::skip] | ||
| string_enum! { | ||
| /// The default outbound network policy. | ||
| #[derive(Debug)] | ||
| pub enum DefaultNetworkPolicy { | ||
| /// Allow outbound network access by default. | ||
| Allow => ["allow"], | ||
| /// Block outbound network access by default. | ||
| Block => ["block"], | ||
| } | ||
| } | ||
|
|
||
| #[rustfmt::skip] | ||
| string_enum! { | ||
| /// The mechanism used to enforce network policy. | ||
| #[derive(Debug)] | ||
| pub enum NetworkEnforcementMode { | ||
| /// Enforce policy through containment capabilities. | ||
| Capabilities => ["capabilities"], | ||
| /// Enforce policy through host firewall rules. | ||
| Firewall => ["firewall"], | ||
| /// Enforce policy through both capabilities and firewall rules. | ||
| Both => ["both"], | ||
| } | ||
| } | ||
|
|
||
| /// One of the proxy configurations accepted by the `0.8.0-alpha` contract. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| pub enum NetworkProxy { | ||
| /// Connect to an existing proxy on a non-zero localhost TCP port. | ||
| #[serde(rename = "localhost")] | ||
| Localhost(NonZeroU16), | ||
| /// Start and use MXC's built-in test proxy. | ||
| #[serde(rename = "builtinTestServer")] | ||
| BuiltinTestServer(True), | ||
| /// Connect through the supplied proxy URL. | ||
| #[serde(rename = "url")] | ||
| Url(String), | ||
| } | ||
|
|
||
| /// Network access policy shared by the stable containment backends. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct Network { | ||
| /// Optional default network posture. | ||
| #[serde(default)] | ||
| pub default_policy: OptionalField<DefaultNetworkPolicy>, | ||
| /// Optional network enforcement mechanism. | ||
| #[serde(default)] | ||
| pub enforcement_mode: OptionalField<NetworkEnforcementMode>, | ||
| /// Optional hosts allowed when the default policy blocks access. | ||
| #[serde(default)] | ||
| pub allowed_hosts: OptionalField<Vec<String>>, | ||
| /// Optional hosts blocked when the default policy allows access. | ||
| #[serde(default)] | ||
| pub blocked_hosts: OptionalField<Vec<String>>, | ||
| /// Optional permission to bind and accept local network connections. | ||
| #[serde(default)] | ||
| pub allow_local_network: OptionalField<bool>, | ||
| /// Optional proxy configuration. | ||
| #[serde(default)] | ||
| pub proxy: OptionalField<NetworkProxy>, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use super::experimental::OneShotExperimental; | ||
| use super::network::Network; | ||
| use super::primitives::OptionalField; | ||
| use super::stable::{ | ||
| Fallback, Filesystem, Lifecycle, Lxc, Process, ProcessContainer, Seatbelt, Ui, | ||
| }; | ||
| use crate::dev::Version; | ||
|
|
||
| #[rustfmt::skip] | ||
| string_enum! { | ||
| /// Containment selections available in `0.8.0-alpha`. | ||
| #[derive(Debug)] | ||
| pub enum Containment { | ||
| // Stable-candidate values. | ||
| /// Select the host's native process-containment backend. | ||
| Process => ["process"], | ||
| /// Select the Windows ProcessContainer backend. | ||
| ProcessContainer => ["processcontainer", "appcontainer"], | ||
| /// Select the Linux LXC backend. | ||
| Lxc => ["lxc"], | ||
| /// Select the Linux Bubblewrap backend. | ||
| Bubblewrap => ["bubblewrap"], | ||
| /// Select the macOS Seatbelt backend. | ||
| Seatbelt => ["seatbelt", "macos_sandbox"], | ||
|
|
||
| // Development-only values. | ||
| /// Select the host's VM-class containment backend. | ||
| Vm => ["vm"], | ||
| /// Select the Windows Sandbox backend. | ||
| WindowsSandbox => ["windows_sandbox"], | ||
| /// Select the NanVix micro-VM backend. | ||
| Microvm => ["microvm"], | ||
| /// Select the Hyperlight micro-VM backend. | ||
| Hyperlight => ["hyperlight"], | ||
| /// Select the WSL container backend. | ||
| Wslc => ["wslc"], | ||
| /// Select the Windows IsolationSession backend. | ||
| IsolationSession => ["isolation_session"], | ||
| } | ||
| } | ||
|
|
||
| /// A complete one-shot `0.8.0-alpha` configuration request. | ||
| #[derive(Debug, serde::Deserialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
| pub struct Request { | ||
| /// Optional JSON Schema reference for editor validation. | ||
| #[serde(rename = "$schema", default)] | ||
| pub schema: OptionalField<String>, | ||
| /// Optional human-readable annotation ignored by the runtime. | ||
| #[serde(rename = "_comment", default)] | ||
| pub comment: OptionalField<serde_json::Value>, | ||
| /// The exact contract version marker. | ||
| pub version: Version, | ||
| /// Optional externally assigned container identifier. | ||
| #[serde(default)] | ||
| pub container_id: OptionalField<String>, | ||
| /// Optional containment selection. | ||
| #[serde(default)] | ||
| pub containment: OptionalField<Containment>, | ||
| /// Optional lifecycle settings. | ||
| #[serde(default)] | ||
| pub lifecycle: OptionalField<Lifecycle>, | ||
| /// The process to execute. | ||
| pub process: Process, | ||
| /// Optional filesystem policy. | ||
| #[serde(default)] | ||
| pub filesystem: OptionalField<Filesystem>, | ||
| /// Optional fallback consent. | ||
| #[serde(default)] | ||
| pub fallback: OptionalField<Fallback>, | ||
| /// Optional network policy. | ||
| #[serde(default)] | ||
| pub network: OptionalField<Network>, | ||
| /// Optional cross-platform user-interface policy. | ||
| #[serde(default)] | ||
| pub ui: OptionalField<Ui>, | ||
| /// Optional ProcessContainer settings. | ||
| /// The legacy `appContainer` spelling is accepted as an alias. | ||
| #[serde(alias = "appContainer", default)] | ||
| pub process_container: OptionalField<ProcessContainer>, | ||
| /// Optional LXC distribution settings. | ||
| #[serde(default)] | ||
| pub lxc: OptionalField<Lxc>, | ||
| /// Optional macOS Seatbelt configuration. | ||
| #[serde(alias = "macos_sandbox", default)] | ||
| pub seatbelt: OptionalField<Seatbelt>, | ||
| /// Optional experimental settings. | ||
| #[serde(default)] | ||
| pub experimental: OptionalField<OneShotExperimental>, | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.