composefs_storage/config.rs
1//! Configuration parsing for container storage.
2//!
3//! This module provides structures for parsing storage.conf files used by
4//! containers-storage. Configuration files define storage locations, drivers,
5//! and additional read-only image stores.
6//!
7//! # Overview
8//!
9//! Container storage configuration is typically found in:
10//! - System-wide: `/etc/containers/storage.conf`
11//! - User-specific: `~/.config/containers/storage.conf`
12//!
13//! The configuration uses TOML format and specifies the storage driver
14//! (overlay, btrfs, etc.), root paths, and additional layer/image stores.
15//!
16//! # Configuration Structure
17//!
18//! A typical storage.conf file looks like:
19//! ```toml
20//! [storage]
21//! driver = "overlay"
22//! root = "/var/lib/containers/storage"
23//! run_root = "/run/containers/storage"
24//!
25//! # Additional read-only image stores
26//! image_stores = [
27//! "/usr/share/containers/storage"
28//! ]
29//!
30//! # Additional layer stores configuration
31//! [[storage.layer_stores]]
32//! path = "/mnt/layers"
33//! with_reference = true
34//! ```
35
36use serde::Deserialize;
37use std::path::PathBuf;
38
39/// Storage configuration, typically parsed from storage.conf files.
40///
41/// Configuration files are searched in:
42/// - `/etc/containers/storage.conf`
43/// - `$HOME/.config/containers/storage.conf`
44#[derive(Debug, Clone, Deserialize)]
45pub struct StorageConfig {
46 /// Storage driver name (should be "overlay" for this library).
47 #[serde(default)]
48 pub driver: String,
49
50 /// Primary storage root path.
51 #[serde(default)]
52 pub root: PathBuf,
53
54 /// Runtime root for transient data.
55 #[serde(default)]
56 pub run_root: PathBuf,
57
58 /// Additional read-only image stores.
59 #[serde(default)]
60 pub image_stores: Vec<PathBuf>,
61
62 /// Additional layer stores configuration.
63 #[serde(default)]
64 pub layer_stores: Vec<AdditionalLayerStore>,
65}
66
67/// Configuration for an additional layer store.
68#[derive(Debug, Clone, Deserialize)]
69pub struct AdditionalLayerStore {
70 /// Path to the additional layer store.
71 pub path: PathBuf,
72
73 /// Whether to use base64-encoded references in paths.
74 #[serde(default)]
75 pub with_reference: bool,
76}
77
78impl StorageConfig {
79 /// Parse storage configuration from TOML content.
80 ///
81 /// # Errors
82 ///
83 /// Returns an error if the TOML content is invalid.
84 pub fn from_toml(content: &str) -> Result<Self, toml::de::Error> {
85 toml::from_str(content)
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_parse_basic_config() {
95 let config_str = r#"
96driver = "overlay"
97root = "/var/lib/containers/storage"
98"#;
99 let config = StorageConfig::from_toml(config_str).unwrap();
100 assert_eq!(config.driver, "overlay");
101 assert_eq!(config.root, PathBuf::from("/var/lib/containers/storage"));
102 }
103
104 #[test]
105 fn test_parse_with_layer_stores() {
106 let config_str = r#"
107driver = "overlay"
108root = "/var/lib/containers/storage"
109
110[[layer_stores]]
111path = "/mnt/layers"
112with_reference = true
113"#;
114 let config = StorageConfig::from_toml(config_str).unwrap();
115 assert_eq!(config.layer_stores.len(), 1);
116 assert_eq!(config.layer_stores[0].path, PathBuf::from("/mnt/layers"));
117 assert!(config.layer_stores[0].with_reference);
118 }
119}