mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
refactor(settings): stage 6.3b promote sandbox runtime types into fabro-sandbox
Moves the sandbox runtime types from `fabro-types/src/settings/sandbox.rs` into a new `fabro-sandbox/src/config.rs` module: - `SandboxSettings`, `LocalSandboxSettings`, `DaytonaSettings`, `DaytonaSnapshotSettings`, `DaytonaNetwork`, `DockerfileSource`, `WorktreeMode` (with the custom serde `DaytonaNetwork` serialize/deserialize impls intact). - `bridge_sandbox` and `bridge_worktree_mode` (v2 `RunSandboxLayer` → `SandboxSettings` converters) also move from `fabro-types/src/settings/v2/to_runtime.rs` into the new config module. `fabro-sandbox/src/daytona/mod.rs` and `sandbox_spec.rs` update to import from the crate-local `config` module instead of `fabro_types::settings::sandbox`. The daytona module still re-exports `DaytonaSettings as DaytonaConfig` etc., so no breaking changes for callers of `fabro_sandbox::daytona::*`. Consumer updates: - `fabro-workflow/src/operations/start.rs` and `pipeline/types.rs` now import `WorktreeMode`, `SandboxSettings` (as `sandbox_config` alias), `bridge_sandbox`, and `bridge_worktree_mode` from `fabro_sandbox::config`. - `fabro-server/src/run_manifest.rs` imports `bridge_sandbox` from `fabro_sandbox::config`. `to_runtime.rs` in fabro-types shrinks to just the three remaining helpers tied to the legacy `run.rs` module types (`bridge_merge_strategy`, `bridge_pull_request`, `bridge_run_artifacts`). Those move out in the next 6.3b pass when the `run.rs` module itself moves. Five of the seven legacy runtime type modules are now gone; two remain (run, server). 3,758 workspace tests pass. `cargo fmt --check --all` and `cargo clippy --workspace -- -D warnings` are clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5905befa8d
commit
0883cf77ee
9 changed files with 120 additions and 107 deletions
|
|
@ -1,5 +1,20 @@
|
|||
//! Sandbox configuration runtime types.
|
||||
//!
|
||||
//! These types are the runtime shape that the sandbox providers consume.
|
||||
//! The v2 parse tree lives in `fabro_types::settings::v2::run::RunSandboxLayer`.
|
||||
//! Conversion from the v2 shape lives in [`bridge_sandbox`].
|
||||
//!
|
||||
//! The `DaytonaSettings`/`DaytonaSnapshotSettings` names are kept for
|
||||
//! backward compatibility with the old import path; [`crate::daytona`]
|
||||
//! continues to re-export them under `DaytonaConfig`/`DaytonaSnapshotConfig`
|
||||
//! aliases.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use fabro_types::settings::v2::InterpString;
|
||||
use fabro_types::settings::v2::run::{
|
||||
DaytonaDockerfileLayer, DaytonaNetworkLayer, RunSandboxLayer, WorktreeMode as V2WorktreeMode,
|
||||
};
|
||||
use serde::de::{self, MapAccess, Visitor};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
|
@ -13,7 +28,7 @@ pub struct DaytonaSettings {
|
|||
pub skip_clone: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, crate::Combine)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum DaytonaNetwork {
|
||||
Block,
|
||||
AllowAll,
|
||||
|
|
@ -98,7 +113,7 @@ impl<'de> Deserialize<'de> for DaytonaNetwork {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, crate::Combine)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum DockerfileSource {
|
||||
Inline(String),
|
||||
|
|
@ -114,7 +129,7 @@ pub struct DaytonaSnapshotSettings {
|
|||
pub dockerfile: Option<DockerfileSource>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, crate::Combine)]
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum WorktreeMode {
|
||||
Always,
|
||||
|
|
@ -139,3 +154,81 @@ pub struct SandboxSettings {
|
|||
pub daytona: Option<DaytonaSettings>,
|
||||
pub env: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
/// Convert a v2 [`RunSandboxLayer`] into the runtime [`SandboxSettings`] shape.
|
||||
#[must_use]
|
||||
pub fn bridge_sandbox(sb: &RunSandboxLayer) -> SandboxSettings {
|
||||
SandboxSettings {
|
||||
provider: sb.provider.clone(),
|
||||
preserve: sb.preserve,
|
||||
devcontainer: sb.devcontainer,
|
||||
local: sb.local.as_ref().map(|local| LocalSandboxSettings {
|
||||
worktree_mode: local
|
||||
.worktree_mode
|
||||
.map(bridge_worktree_mode)
|
||||
.unwrap_or_default(),
|
||||
}),
|
||||
daytona: sb.daytona.as_ref().map(|d| DaytonaSettings {
|
||||
auto_stop_interval: d.auto_stop_interval,
|
||||
labels: if d.labels.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(d.labels.clone())
|
||||
},
|
||||
snapshot: d.snapshot.as_ref().and_then(|s| {
|
||||
s.name.as_ref().map(|name| DaytonaSnapshotSettings {
|
||||
name: name.clone(),
|
||||
cpu: s.cpu,
|
||||
memory: s.memory.map(|sz| size_to_gb_i32(sz.as_bytes())),
|
||||
disk: s.disk.map(|sz| size_to_gb_i32(sz.as_bytes())),
|
||||
dockerfile: s.dockerfile.as_ref().map(|d| match d {
|
||||
DaytonaDockerfileLayer::Inline(text) => {
|
||||
DockerfileSource::Inline(text.clone())
|
||||
}
|
||||
DaytonaDockerfileLayer::Path { path } => {
|
||||
DockerfileSource::Path { path: path.clone() }
|
||||
}
|
||||
}),
|
||||
})
|
||||
}),
|
||||
network: d.network.as_ref().map(|n| match n {
|
||||
DaytonaNetworkLayer::Block => DaytonaNetwork::Block,
|
||||
DaytonaNetworkLayer::AllowAll => DaytonaNetwork::AllowAll,
|
||||
DaytonaNetworkLayer::AllowList { allow_list } => {
|
||||
DaytonaNetwork::AllowList(allow_list.clone())
|
||||
}
|
||||
}),
|
||||
skip_clone: d.skip_clone.unwrap_or(false),
|
||||
}),
|
||||
env: if sb.env.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
sb.env
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), interp_to_string(v)))
|
||||
.collect(),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a v2 [`V2WorktreeMode`] into the runtime [`WorktreeMode`].
|
||||
#[must_use]
|
||||
pub fn bridge_worktree_mode(m: V2WorktreeMode) -> WorktreeMode {
|
||||
match m {
|
||||
V2WorktreeMode::Always => WorktreeMode::Always,
|
||||
V2WorktreeMode::Clean => WorktreeMode::Clean,
|
||||
V2WorktreeMode::Dirty => WorktreeMode::Dirty,
|
||||
V2WorktreeMode::Never => WorktreeMode::Never,
|
||||
}
|
||||
}
|
||||
|
||||
fn interp_to_string(value: &InterpString) -> String {
|
||||
value.as_source()
|
||||
}
|
||||
|
||||
fn size_to_gb_i32(bytes: u64) -> i32 {
|
||||
let gb = bytes / 1_000_000_000;
|
||||
i32::try_from(gb).unwrap_or(i32::MAX)
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ use tokio_util::sync::CancellationToken;
|
|||
const WORKING_DIRECTORY: &str = "/home/daytona/workspace";
|
||||
const DEFAULT_SNAPSHOT: &str = "daytona-medium";
|
||||
|
||||
pub use fabro_types::settings::sandbox::{
|
||||
pub use crate::config::{
|
||||
DaytonaNetwork, DaytonaSettings as DaytonaConfig,
|
||||
DaytonaSnapshotSettings as DaytonaSnapshotConfig, DockerfileSource,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod config;
|
||||
pub mod sandbox;
|
||||
pub mod sandbox_spec;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use fabro_types::{RunId, settings::WorktreeMode};
|
||||
use crate::config::WorktreeMode;
|
||||
use fabro_types::RunId;
|
||||
|
||||
#[cfg(any(feature = "docker", feature = "daytona"))]
|
||||
use anyhow::anyhow;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use fabro_graphviz::graph::{Graph, is_llm_handler_type};
|
|||
use fabro_graphviz::render::apply_direction;
|
||||
use fabro_llm::Provider;
|
||||
use fabro_model::Catalog;
|
||||
use fabro_sandbox::config::bridge_sandbox;
|
||||
use fabro_sandbox::daytona::DaytonaConfig;
|
||||
use fabro_sandbox::{DockerSandboxOptions, Sandbox, SandboxProvider, SandboxSpec};
|
||||
use fabro_types::RunId;
|
||||
|
|
@ -23,7 +24,6 @@ use fabro_types::settings::v2::run::{
|
|||
ApprovalMode, DaytonaDockerfileLayer, RunExecutionLayer, RunLayer, RunMode, RunModelLayer,
|
||||
RunSandboxLayer,
|
||||
};
|
||||
use fabro_types::settings::v2::to_runtime::bridge_sandbox;
|
||||
use fabro_util::check_report::{CheckDetail, CheckReport, CheckResult, CheckSection, CheckStatus};
|
||||
use fabro_validate::Severity;
|
||||
use fabro_workflow::error::FabroError;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
//! accessors, at which point this module goes away.
|
||||
|
||||
pub mod run;
|
||||
pub mod sandbox;
|
||||
pub mod server;
|
||||
pub mod v2;
|
||||
|
||||
|
|
@ -28,10 +27,6 @@ pub use run::{
|
|||
ArtifactsSettings, CheckpointSettings, GitHubSettings, LlmSettings, MergeStrategy,
|
||||
PullRequestSettings, SetupSettings,
|
||||
};
|
||||
pub use sandbox::{
|
||||
DaytonaNetwork, DaytonaSettings, DaytonaSnapshotSettings, DockerfileSource,
|
||||
LocalSandboxSettings, SandboxSettings, WorktreeMode,
|
||||
};
|
||||
pub use server::{
|
||||
ApiAuthStrategy, ApiSettings, ArtifactStorageBackend, ArtifactStorageSettings, AuthProvider,
|
||||
AuthSettings, FeaturesSettings, GitAuthorSettings, GitProvider, GitSettings, LogSettings,
|
||||
|
|
|
|||
|
|
@ -1,92 +1,24 @@
|
|||
//! v2 → runtime-type conversion helpers.
|
||||
//!
|
||||
//! The runtime types in `fabro_types::settings::{run,sandbox}` are the
|
||||
//! shapes that downstream crates (fabro-workflow, fabro-sandbox) still
|
||||
//! consume at runtime. Each helper here reads the v2 parse tree and
|
||||
//! builds the equivalent runtime value.
|
||||
//! Everything but the pull-request / artifacts / merge-strategy conversion
|
||||
//! has moved out of this module into the consumer crate that owns the
|
||||
//! target runtime type:
|
||||
//!
|
||||
//! Hook bridging has moved to `fabro_hooks::config::bridge_hook`; MCP
|
||||
//! bridging has moved to `fabro_mcp::config::{bridge_mcps, bridge_mcp_entry}`.
|
||||
//! Consumer crates will pull the rest of these helpers into their own
|
||||
//! crates in follow-up 6.3b passes.
|
||||
//! - Hook bridging: [`fabro_hooks::config::bridge_hook`]
|
||||
//! - MCP bridging: [`fabro_mcp::config::bridge_mcp_entry`] /
|
||||
//! [`fabro_mcp::config::bridge_mcps`]
|
||||
//! - Sandbox bridging: [`fabro_sandbox::config::bridge_sandbox`] /
|
||||
//! [`fabro_sandbox::config::bridge_worktree_mode`]
|
||||
//!
|
||||
//! Pull-request / artifacts / merge-strategy still live here because their
|
||||
//! target runtime types (`PullRequestSettings`, `ArtifactsSettings`,
|
||||
//! `MergeStrategy`) are still in `fabro-types::settings::run`. When that
|
||||
//! module moves into `fabro-workflow` the remaining helpers will follow.
|
||||
|
||||
use super::interp::InterpString;
|
||||
use super::run::{
|
||||
MergeStrategy as V2MergeStrategy, RunArtifactsLayer, RunPullRequestLayer, RunSandboxLayer,
|
||||
WorktreeMode as V2WorktreeMode,
|
||||
};
|
||||
use super::run::{MergeStrategy as V2MergeStrategy, RunArtifactsLayer, RunPullRequestLayer};
|
||||
use crate::settings::run::{
|
||||
ArtifactsSettings, MergeStrategy as OldMergeStrategy, PullRequestSettings,
|
||||
};
|
||||
use crate::settings::sandbox::{
|
||||
DaytonaNetwork, DaytonaSettings, DaytonaSnapshotSettings, DockerfileSource,
|
||||
LocalSandboxSettings, SandboxSettings, WorktreeMode as OldWorktreeMode,
|
||||
};
|
||||
|
||||
pub fn bridge_sandbox(sb: &RunSandboxLayer) -> SandboxSettings {
|
||||
SandboxSettings {
|
||||
provider: sb.provider.clone(),
|
||||
preserve: sb.preserve,
|
||||
devcontainer: sb.devcontainer,
|
||||
local: sb.local.as_ref().map(|local| LocalSandboxSettings {
|
||||
worktree_mode: local
|
||||
.worktree_mode
|
||||
.map(bridge_worktree_mode)
|
||||
.unwrap_or_default(),
|
||||
}),
|
||||
daytona: sb.daytona.as_ref().map(|d| DaytonaSettings {
|
||||
auto_stop_interval: d.auto_stop_interval,
|
||||
labels: if d.labels.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(d.labels.clone())
|
||||
},
|
||||
snapshot: d.snapshot.as_ref().and_then(|s| {
|
||||
s.name.as_ref().map(|name| DaytonaSnapshotSettings {
|
||||
name: name.clone(),
|
||||
cpu: s.cpu,
|
||||
memory: s.memory.map(|sz| size_to_gb_i32(sz.as_bytes())),
|
||||
disk: s.disk.map(|sz| size_to_gb_i32(sz.as_bytes())),
|
||||
dockerfile: s.dockerfile.as_ref().map(|d| match d {
|
||||
super::run::DaytonaDockerfileLayer::Inline(text) => {
|
||||
DockerfileSource::Inline(text.clone())
|
||||
}
|
||||
super::run::DaytonaDockerfileLayer::Path { path } => {
|
||||
DockerfileSource::Path { path: path.clone() }
|
||||
}
|
||||
}),
|
||||
})
|
||||
}),
|
||||
network: d.network.as_ref().map(|n| match n {
|
||||
super::run::DaytonaNetworkLayer::Block => DaytonaNetwork::Block,
|
||||
super::run::DaytonaNetworkLayer::AllowAll => DaytonaNetwork::AllowAll,
|
||||
super::run::DaytonaNetworkLayer::AllowList { allow_list } => {
|
||||
DaytonaNetwork::AllowList(allow_list.clone())
|
||||
}
|
||||
}),
|
||||
skip_clone: d.skip_clone.unwrap_or(false),
|
||||
}),
|
||||
env: if sb.env.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
sb.env
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), interp_to_string(v)))
|
||||
.collect(),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bridge_worktree_mode(m: V2WorktreeMode) -> OldWorktreeMode {
|
||||
match m {
|
||||
V2WorktreeMode::Always => OldWorktreeMode::Always,
|
||||
V2WorktreeMode::Clean => OldWorktreeMode::Clean,
|
||||
V2WorktreeMode::Dirty => OldWorktreeMode::Dirty,
|
||||
V2WorktreeMode::Never => OldWorktreeMode::Never,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bridge_merge_strategy(m: V2MergeStrategy) -> OldMergeStrategy {
|
||||
match m {
|
||||
|
|
@ -113,12 +45,3 @@ pub fn bridge_run_artifacts(artifacts: &RunArtifactsLayer) -> ArtifactsSettings
|
|||
include: artifacts.include.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn interp_to_string(value: &InterpString) -> String {
|
||||
value.as_source()
|
||||
}
|
||||
|
||||
fn size_to_gb_i32(bytes: u64) -> i32 {
|
||||
let gb = bytes / 1_000_000_000;
|
||||
i32::try_from(gb).unwrap_or(i32::MAX)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ use fabro_hooks::config::bridge_hook;
|
|||
use fabro_interview::{AutoApproveInterviewer, Interviewer};
|
||||
use fabro_mcp::config::bridge_mcp_entry;
|
||||
use fabro_model::{Catalog, FallbackTarget, Provider};
|
||||
use fabro_sandbox::config::{
|
||||
self as sandbox_config, WorktreeMode, bridge_sandbox, bridge_worktree_mode,
|
||||
};
|
||||
use fabro_sandbox::{SandboxProvider, SandboxSpec};
|
||||
use fabro_types::RunId;
|
||||
use fabro_types::settings::sandbox::{self as sandbox_config, WorktreeMode};
|
||||
use fabro_types::settings::v2::run::ModelRefOrSplice;
|
||||
use fabro_types::settings::v2::to_runtime::{
|
||||
bridge_pull_request, bridge_sandbox, bridge_worktree_mode,
|
||||
};
|
||||
use fabro_types::settings::v2::to_runtime::bridge_pull_request;
|
||||
use fabro_types::settings::v2::{InterpString, SettingsFile};
|
||||
|
||||
use crate::artifact_upload::ArtifactSink;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use fabro_llm::Provider;
|
|||
use fabro_mcp::config::McpServerSettings;
|
||||
use fabro_model::FallbackTarget;
|
||||
use fabro_sandbox::SandboxSpec;
|
||||
use fabro_sandbox::config::WorktreeMode;
|
||||
use fabro_types::RunId;
|
||||
use fabro_types::settings::sandbox::WorktreeMode;
|
||||
use fabro_validate::Diagnostic;
|
||||
|
||||
use crate::artifact_upload::ArtifactSink;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue