rusty_stack/installers/components/
rocm_smi.rs1use crate::installers::common::DistroFacade;
13use crate::platform::detection::DistroFamily;
14use std::path::PathBuf;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct ShellCommand {
23 pub program: String,
25 pub args: Vec<String>,
27 pub env: Vec<(String, String)>,
29 pub working_dir: Option<PathBuf>,
31}
32
33impl ShellCommand {
34 pub fn to_command_string(&self) -> String {
36 let env_prefix = self
37 .env
38 .iter()
39 .map(|(k, v)| format!("{k}={v}"))
40 .collect::<Vec<_>>()
41 .join(" ");
42 let cmd = if self.args.is_empty() {
43 self.program.clone()
44 } else {
45 format!("{} {}", self.program, self.args.join(" "))
46 };
47 if env_prefix.is_empty() {
48 cmd
49 } else {
50 format!("{env_prefix} {cmd}")
51 }
52 }
53}
54
55#[derive(Default)]
59pub struct RocmSmiInstaller;
60
61impl RocmSmiInstaller {
62 pub fn new() -> Self {
64 Self
65 }
66
67 pub fn git_clone_url(&self) -> &'static str {
73 "https://github.com/RadeonOpenCompute/rocm_smi_lib.git"
74 }
75
76 pub fn build_git_clone_command(&self, target_dir: &str) -> ShellCommand {
78 ShellCommand {
79 program: "git".to_string(),
80 args: vec![
81 "clone".to_string(),
82 self.git_clone_url().to_string(),
83 target_dir.to_string(),
84 ],
85 env: vec![],
86 working_dir: None,
87 }
88 }
89
90 pub fn build_package_install_command(&self, distro: &DistroFacade) -> ShellCommand {
102 let (program, args) = match distro.family() {
103 DistroFamily::Debian => (
104 "sudo".to_string(),
105 vec![
106 "apt-get".to_string(),
107 "install".to_string(),
108 "-y".to_string(),
109 "rocm-smi".to_string(),
110 ],
111 ),
112 DistroFamily::Rhel => (
113 "sudo".to_string(),
114 vec![
115 "dnf".to_string(),
116 "install".to_string(),
117 "-y".to_string(),
118 "rocm-smi".to_string(),
119 ],
120 ),
121 DistroFamily::Arch => (
122 "sudo".to_string(),
123 vec![
124 "pacman".to_string(),
125 "-S".to_string(),
126 "--needed".to_string(),
127 "--noconfirm".to_string(),
128 "rocm-smi-lib".to_string(),
129 ],
130 ),
131 DistroFamily::Suse => (
132 "sudo".to_string(),
133 vec![
134 "zypper".to_string(),
135 "install".to_string(),
136 "-y".to_string(),
137 "rocm-smi".to_string(),
138 ],
139 ),
140 _ => (
141 "sudo".to_string(),
142 vec![
143 "apt-get".to_string(),
144 "install".to_string(),
145 "-y".to_string(),
146 "rocm-smi".to_string(),
147 ],
148 ),
149 };
150
151 ShellCommand {
152 program,
153 args,
154 env: vec![],
155 working_dir: None,
156 }
157 }
158
159 pub fn build_package_update_command(&self, distro: &DistroFacade) -> ShellCommand {
161 let (program, args) = match distro.family() {
162 DistroFamily::Debian => (
163 "sudo".to_string(),
164 vec![
165 "apt-get".to_string(),
166 "update".to_string(),
167 "-y".to_string(),
168 ],
169 ),
170 DistroFamily::Rhel => (
171 "sudo".to_string(),
172 vec!["dnf".to_string(), "makecache".to_string()],
173 ),
174 DistroFamily::Arch => (
175 "sudo".to_string(),
176 vec!["pacman".to_string(), "-Sy".to_string()],
177 ),
178 DistroFamily::Suse => (
179 "sudo".to_string(),
180 vec!["zypper".to_string(), "refresh".to_string()],
181 ),
182 _ => (
183 "sudo".to_string(),
184 vec![
185 "apt-get".to_string(),
186 "update".to_string(),
187 "-y".to_string(),
188 ],
189 ),
190 };
191
192 ShellCommand {
193 program,
194 args,
195 env: vec![],
196 working_dir: None,
197 }
198 }
199}
200
201#[cfg(test)]
206mod tests {
207 use super::*;
208 use crate::platform::detection::{DistroInfo, PackageManager};
209
210 #[test]
213 fn test_git_clone_url() {
214 let installer = RocmSmiInstaller::new();
215 assert_eq!(
216 installer.git_clone_url(),
217 "https://github.com/RadeonOpenCompute/rocm_smi_lib.git"
218 );
219 }
220
221 #[test]
222 fn test_git_clone_command() {
223 let installer = RocmSmiInstaller::new();
224 let cmd = installer.build_git_clone_command("/tmp/rocm_smi");
225 assert_eq!(cmd.program, "git");
226 assert!(cmd.args.contains(&"clone".to_string()));
227 assert!(cmd
228 .args
229 .iter()
230 .any(|a| a.contains("RadeonOpenCompute/rocm_smi_lib")));
231 }
232
233 #[test]
234 fn test_package_install_debian() {
235 let installer = RocmSmiInstaller::new();
236 let distro = DistroFacade::from_info(DistroInfo {
237 id: "ubuntu".to_string(),
238 family: DistroFamily::Debian,
239 pkg_manager: PackageManager::Apt,
240 ..Default::default()
241 });
242 let cmd = installer.build_package_install_command(&distro);
243 assert_eq!(cmd.program, "sudo");
244 assert!(cmd.args.contains(&"apt-get".to_string()));
245 assert!(cmd.args.contains(&"install".to_string()));
246 assert!(cmd.args.contains(&"-y".to_string()));
247 assert!(cmd.args.contains(&"rocm-smi".to_string()));
248 }
249
250 #[test]
251 fn test_package_install_rhel() {
252 let installer = RocmSmiInstaller::new();
253 let distro = DistroFacade::from_info(DistroInfo {
254 id: "fedora".to_string(),
255 family: DistroFamily::Rhel,
256 pkg_manager: PackageManager::Dnf,
257 ..Default::default()
258 });
259 let cmd = installer.build_package_install_command(&distro);
260 assert_eq!(cmd.program, "sudo");
261 assert!(cmd.args.contains(&"dnf".to_string()));
262 assert!(cmd.args.contains(&"install".to_string()));
263 assert!(cmd.args.contains(&"rocm-smi".to_string()));
264 }
265
266 #[test]
267 fn test_package_install_arch() {
268 let installer = RocmSmiInstaller::new();
269 let distro = DistroFacade::from_info(DistroInfo {
270 id: "arch".to_string(),
271 family: DistroFamily::Arch,
272 pkg_manager: PackageManager::Pacman,
273 ..Default::default()
274 });
275 let cmd = installer.build_package_install_command(&distro);
276 assert_eq!(cmd.program, "sudo");
277 assert!(cmd.args.contains(&"pacman".to_string()));
278 assert!(cmd.args.contains(&"-S".to_string()));
279 assert!(cmd.args.contains(&"--needed".to_string()));
280 assert!(cmd.args.contains(&"--noconfirm".to_string()));
281 assert!(cmd.args.contains(&"rocm-smi-lib".to_string()));
282 }
283
284 #[test]
285 fn test_package_install_suse() {
286 let installer = RocmSmiInstaller::new();
287 let distro = DistroFacade::from_info(DistroInfo {
288 id: "opensuse".to_string(),
289 family: DistroFamily::Suse,
290 pkg_manager: PackageManager::Zypper,
291 ..Default::default()
292 });
293 let cmd = installer.build_package_install_command(&distro);
294 assert_eq!(cmd.program, "sudo");
295 assert!(cmd.args.contains(&"zypper".to_string()));
296 assert!(cmd.args.contains(&"install".to_string()));
297 assert!(cmd.args.contains(&"rocm-smi".to_string()));
298 }
299
300 #[test]
301 fn test_package_update_debian() {
302 let installer = RocmSmiInstaller::new();
303 let distro = DistroFacade::from_info(DistroInfo {
304 id: "ubuntu".to_string(),
305 family: DistroFamily::Debian,
306 pkg_manager: PackageManager::Apt,
307 ..Default::default()
308 });
309 let cmd = installer.build_package_update_command(&distro);
310 assert!(cmd.args.contains(&"apt-get".to_string()));
311 assert!(cmd.args.contains(&"update".to_string()));
312 }
313}