Create a sandbox with default settings.
(
server: &str,
gateway_name: &str,
config: SandboxCreateConfig<'_>,
tls: &TlsOptions,
)
| 1818 | |
| 1819 | /// Create a sandbox with default settings. |
| 1820 | pub async fn sandbox_create( |
| 1821 | server: &str, |
| 1822 | gateway_name: &str, |
| 1823 | config: SandboxCreateConfig<'_>, |
| 1824 | tls: &TlsOptions, |
| 1825 | ) -> Result<()> { |
| 1826 | let SandboxCreateConfig { |
| 1827 | name, |
| 1828 | from, |
| 1829 | uploads, |
| 1830 | keep, |
| 1831 | gpu_requirements, |
| 1832 | cpu, |
| 1833 | memory, |
| 1834 | driver_config_json, |
| 1835 | editor, |
| 1836 | providers, |
| 1837 | policy, |
| 1838 | forward, |
| 1839 | command, |
| 1840 | tty_override, |
| 1841 | auto_providers_override, |
| 1842 | labels, |
| 1843 | environment, |
| 1844 | approval_mode, |
| 1845 | } = config; |
| 1846 | |
| 1847 | if editor.is_some() && !command.is_empty() { |
| 1848 | return Err(miette::miette!( |
| 1849 | "--editor cannot be used with a trailing command; use `openshell sandbox connect <name> --editor ...` after the sandbox is ready" |
| 1850 | )); |
| 1851 | } |
| 1852 | |
| 1853 | // Check port availability *before* creating the sandbox so we don't |
| 1854 | // leave an orphaned sandbox behind when the forward would fail. |
| 1855 | if let Some(ref spec) = forward { |
| 1856 | openshell_core::forward::check_port_available(spec)?; |
| 1857 | } |
| 1858 | |
| 1859 | let mut client = grpc_client(server, tls).await.wrap_err_with(|| { |
| 1860 | format!( |
| 1861 | "failed to connect to gateway '{gateway_name}' at {server}. \ |
| 1862 | Start the gateway service with the installed package manager, \ |
| 1863 | or register a different endpoint with `openshell gateway add <endpoint>`." |
| 1864 | ) |
| 1865 | })?; |
| 1866 | let effective_server = server.to_string(); |
| 1867 | let effective_tls = tls.clone(); |
| 1868 | |
| 1869 | // Resolve the --from flag into a container image reference, building from |
| 1870 | // a Dockerfile first if necessary. |
| 1871 | let image: Option<String> = match from { |
| 1872 | Some(val) => { |
| 1873 | let resolved = resolve_from(val)?; |
| 1874 | match resolved { |
| 1875 | ResolvedSource::Image(img) => Some(img), |
| 1876 | ResolvedSource::Dockerfile { |
| 1877 | dockerfile, |