-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathget_splunk_location.rs
More file actions
103 lines (95 loc) · 3.4 KB
/
Copy pathget_splunk_location.rs
File metadata and controls
103 lines (95 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! Splunk installation location detection.
//!
//! This module provides utilities to automatically detect the Splunk installation
//! directory structure based on the current executable's location.
use std::path::PathBuf;
/// Represents the key paths in a Splunk installation.
///
/// # Fields
///
/// * `root` - The Splunk installation root directory (e.g., `/opt/splunk`)
/// * `app` - The app directory (e.g., `/opt/splunk/etc/apps/myapp`)
/// * `bin` - The bin directory containing executables (e.g., `/opt/splunk/bin`)
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SplunkLocation {
pub root: PathBuf,
pub app: PathBuf,
pub bin: PathBuf,
}
/// Determine Splunk installation location based on the current executable.
///
/// This function analyzes the path of the currently running executable to
/// determine the Splunk installation directory structure. It works both
/// for executables running within a Splunk installation and for standalone
/// executables.
///
/// # Detection logic
///
/// For Splunk environment (executable path contains "splunk"):
/// - Traverses up from the executable to find the root
/// - Assumes structure: `root/bin/...` → root is 4 levels up from bin
///
/// For non-Splunk environment:
/// - Uses parent directories as fallback locations
/// - `root` = executable's grandparent
/// - `app` = executable's parent
/// - `bin` = executable's directory
///
/// # Returns
///
/// `Result<SplunkLocation, io::Error>` containing the detected paths or an error.
///
/// # Examples
///
/// ```rust,no_run
/// use splunklib_rust::get_splunk_location::get_splunk_location;
///
/// match get_splunk_location() {
/// Ok(loc) => {
/// println!("Root: {:?}", loc.root);
/// println!("App: {:?}", loc.app);
/// println!("Bin: {:?}", loc.bin);
/// }
/// Err(e) => eprintln!("Failed to detect location: {}", e),
/// }
/// ```
pub fn get_splunk_location() -> Result<SplunkLocation, std::io::Error> {
let exe_path = std::env::current_exe()?.canonicalize()?;
// Normalize to ASCII lowercase for a simple "splunk" substring check.
let path_text = exe_path.to_string_lossy().to_ascii_lowercase();
let is_splunk = path_text.contains("splunk");
// exe_path -> bin_dir -> app_parent -> apps_parent -> etc_parent -> root_candidate
let bin_dir = exe_path
.parent()
.map(PathBuf::from)
.unwrap_or_else(|| exe_path.clone());
let app_parent = bin_dir.parent().map(PathBuf::from);
let apps_parent = app_parent
.as_ref()
.and_then(|p| p.parent())
.map(PathBuf::from);
let etc_parent = apps_parent
.as_ref()
.and_then(|p| p.parent())
.map(PathBuf::from);
let root_candidate = etc_parent
.as_ref()
.and_then(|p| p.parent())
.map(PathBuf::from);
let (root, app, bin) = 'logic: {
if is_splunk && let (Some(r), Some(a)) = (root_candidate, app_parent) {
break 'logic (r, a, bin_dir.clone());
}
// Fallback for both Splunk and non-Splunk environments
let fallback_app = bin_dir
.parent()
.map(PathBuf::from)
.unwrap_or_else(|| bin_dir.clone());
let fallback_root = fallback_app
.parent()
.map(PathBuf::from)
.unwrap_or_else(|| fallback_app.clone());
(fallback_root, fallback_app, bin_dir.clone())
};
Ok(SplunkLocation { root, app, bin })
}