@opencode-cloud/core
Advanced tools
+1
-1
| [package] | ||
| name = "opencode-cloud-core" | ||
| version = "4.2.0" | ||
| version = "4.2.1" | ||
| edition = "2024" | ||
@@ -5,0 +5,0 @@ rust-version = "1.88" |
+1
-1
| { | ||
| "name": "@opencode-cloud/core", | ||
| "version": "4.2.0", | ||
| "version": "4.2.1", | ||
| "description": "Core NAPI bindings for opencode-cloud (internal package)", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
+33
-1
@@ -18,3 +18,3 @@ //! Configuration management for opencode-cloud | ||
| pub use paths::{get_config_dir, get_config_path, get_data_dir, get_hosts_path, get_pid_path}; | ||
| pub use schema::{Config, validate_bind_address}; | ||
| pub use schema::{Config, default_mounts, validate_bind_address}; | ||
| pub use validation::{ | ||
@@ -79,2 +79,3 @@ ValidationError, ValidationWarning, display_validation_error, display_validation_warning, | ||
| let config = Config::default(); | ||
| ensure_default_mount_dirs(&config)?; | ||
| save_config(&config)?; | ||
@@ -110,2 +111,3 @@ return Ok(config); | ||
| ensure_default_mount_dirs(&config)?; | ||
| Ok(config) | ||
@@ -147,2 +149,32 @@ } | ||
| fn ensure_default_mount_dirs(config: &Config) -> Result<()> { | ||
| let defaults = default_mounts(); | ||
| if defaults.is_empty() { | ||
| return Ok(()); | ||
| } | ||
| for mount_str in &config.mounts { | ||
| if !defaults.contains(mount_str) { | ||
| continue; | ||
| } | ||
| let parsed = crate::docker::mount::ParsedMount::parse(mount_str) | ||
| .with_context(|| format!("Invalid default mount configured: {mount_str}"))?; | ||
| let path = parsed.host_path.as_path(); | ||
| if path.exists() { | ||
| if !path.is_dir() { | ||
| return Err(anyhow::anyhow!( | ||
| "Default mount path is not a directory: {}", | ||
| path.display() | ||
| )); | ||
| } | ||
| continue; | ||
| } | ||
| fs::create_dir_all(path) | ||
| .with_context(|| format!("Failed to create mount directory: {}", path.display()))?; | ||
| tracing::info!("Created mount directory: {}", path.display()); | ||
| } | ||
| Ok(()) | ||
| } | ||
| #[cfg(test)] | ||
@@ -149,0 +181,0 @@ mod tests { |
+26
-6
@@ -5,2 +5,4 @@ //! Configuration schema for opencode-cloud | ||
| use super::paths::{get_config_dir, get_data_dir}; | ||
| use crate::docker::volume::{MOUNT_CONFIG, MOUNT_PROJECTS, MOUNT_SESSION}; | ||
| use serde::{Deserialize, Serialize}; | ||
@@ -121,3 +123,3 @@ use std::net::{IpAddr, Ipv4Addr}; | ||
| /// Format: ["/host/path:/container/path", "/host:/mnt:ro"] | ||
| #[serde(default)] | ||
| #[serde(default = "default_mounts")] | ||
| pub mounts: Vec<String>, | ||
@@ -178,2 +180,20 @@ } | ||
| pub fn default_mounts() -> Vec<String> { | ||
| let maybe_data_dir = get_data_dir(); | ||
| let maybe_config_dir = get_config_dir(); | ||
| let (Some(data_dir), Some(config_dir)) = (maybe_data_dir, maybe_config_dir) else { | ||
| return Vec::new(); | ||
| }; | ||
| let session_dir = data_dir.join("data"); | ||
| let workspace_dir = data_dir.join("workspace"); | ||
| let config_dir = config_dir.join("container"); | ||
| vec![ | ||
| format!("{}:{MOUNT_SESSION}", session_dir.display()), | ||
| format!("{}:{MOUNT_PROJECTS}", workspace_dir.display()), | ||
| format!("{}:{MOUNT_CONFIG}", config_dir.display()), | ||
| ] | ||
| } | ||
| /// Validate and parse a bind address string | ||
@@ -231,3 +251,3 @@ /// | ||
| update_check: default_update_check(), | ||
| mounts: Vec::new(), | ||
| mounts: default_mounts(), | ||
| } | ||
@@ -316,3 +336,3 @@ } | ||
| assert!(config.users.is_empty()); | ||
| assert!(config.mounts.is_empty()); | ||
| assert_eq!(config.mounts, default_mounts()); | ||
| } | ||
@@ -701,3 +721,3 @@ | ||
| let config = Config::default(); | ||
| assert!(config.mounts.is_empty()); | ||
| assert_eq!(config.mounts, default_mounts()); | ||
| } | ||
@@ -726,7 +746,7 @@ | ||
| fn test_mounts_field_default_on_missing() { | ||
| // Old configs without mounts field should get empty vec | ||
| // Old configs without mounts field should get default mounts | ||
| let json = r#"{"version": 1}"#; | ||
| let config: Config = serde_json::from_str(json).unwrap(); | ||
| assert!(config.mounts.is_empty()); | ||
| assert_eq!(config.mounts, default_mounts()); | ||
| } | ||
| } |
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
312140
0.6%