ceph_async/
ceph_volume.rs1extern crate serde_json;
2
3use crate::ceph::Rados;
4use crate::cmd;
5use crate::error::{RadosError, RadosResult};
6use crate::json::*;
7use crate::CephVersion;
8use crate::JsonData;
9use std::collections::HashMap;
10use std::path::PathBuf;
11use std::process::Command;
12
13#[derive(Serialize, Deserialize, Clone, Debug)]
18pub struct LvmTags {
19 #[serde(rename = "ceph.block_device")]
20 pub block_device: Option<String>,
21 #[serde(rename = "ceph.block_uuid")]
22 pub block_uuid: Option<String>,
23 #[serde(rename = "ceph.cephx_lockbox_secret")]
24 pub cephx_lockbox_secret: Option<String>,
25 #[serde(rename = "ceph.cluster_fsid")]
26 pub cluster_fsid: Option<String>,
27 #[serde(rename = "ceph.cluster_name")]
28 pub cluster_name: Option<String>,
29 #[serde(rename = "ceph.crush_device_class")]
30 pub crush_device_class: Option<String>,
31 #[serde(rename = "ceph.data_device")]
32 pub data_device: Option<String>,
33 #[serde(rename = "ceph.data_uuid")]
34 pub data_uuid: Option<String>,
35 #[serde(rename = "ceph.db_device")]
36 pub db_device: Option<String>,
37 #[serde(rename = "ceph.db_uuid")]
38 pub db_uuid: Option<String>,
39 #[serde(rename = "ceph.encrypted")]
40 pub encrypted: Option<String>,
41 #[serde(rename = "ceph.journal_device")]
42 pub journal_device: Option<String>,
43 #[serde(rename = "ceph.journal_uuid")]
44 pub journal_uuid: Option<String>,
45 #[serde(rename = "ceph.osd_fsid")]
46 pub osd_fsid: Option<String>,
47 #[serde(rename = "ceph.osd_id")]
48 pub osd_id: Option<String>,
49 #[serde(rename = "ceph.type")]
50 pub c_type: Option<String>,
51 #[serde(rename = "ceph.vdo")]
52 pub vdo: Option<String>,
53 #[serde(rename = "ceph.wal_device")]
54 pub wal_device: Option<String>,
55 #[serde(rename = "ceph.wal_uuid")]
56 pub wal_uuid: Option<String>,
57 #[serde(flatten)]
59 pub other_tags: Option<HashMap<String, String>>,
60}
61
62#[derive(Serialize, Deserialize, Clone, Debug)]
63pub struct LvmMeta {
64 pub devices: Vec<String>,
65 pub lv_name: String,
66 pub lv_path: String,
67 pub lv_tags: String,
68 pub lv_uuid: String,
69 pub name: String,
70 pub path: String,
71 pub tags: LvmTags,
72 #[serde(rename = "type")]
73 pub lv_type: String,
74 pub vg_name: String,
75 #[serde(flatten)]
77 pub other_meta: Option<HashMap<String, String>>,
78}
79#[derive(Serialize, Deserialize, Clone, Debug)]
80#[serde(untagged)]
81pub enum LvmData {
82 Osd(LvmMeta),
83 Journal {
84 path: Option<String>,
85 tags: Option<HashMap<String, String>>,
86 #[serde(rename = "type")]
87 j_type: Option<String>,
88 #[serde(flatten)]
90 other_meta: Option<HashMap<String, String>>,
91 },
92 Unknown {
94 #[serde(flatten)]
96 unknown_meta: Option<HashMap<String, String>>,
97 },
98}
99
100#[derive(Serialize, Deserialize, Clone, Debug)]
101pub struct Lvm {
102 #[serde(flatten)]
103 pub metadata: LvmData,
104}
105
106fn check_version(cluster_handle: &Rados) -> RadosResult<()> {
108 let version: CephVersion = cmd::version(cluster_handle)?.parse()?;
109 if version < CephVersion::Luminous {
110 return Err(RadosError::MinVersion(CephVersion::Luminous, version));
111 }
112 Ok(())
113}
114
115pub fn ceph_volume_list(cluster_handle: &Rados) -> RadosResult<HashMap<String, Vec<Lvm>>> {
120 check_version(cluster_handle)?;
121 let output = Command::new("ceph-volume")
122 .args(&["lvm", "list", "--format=json"])
123 .output()?;
124 let lvms: HashMap<String, Vec<Lvm>> =
125 serde_json::from_str(&String::from_utf8_lossy(&output.stdout))?;
126 Ok(lvms)
127}
128
129pub fn ceph_volume_scan(
133 cluster_handle: &Rados,
134 osd_path: Option<PathBuf>,
135) -> RadosResult<JsonData> {
136 check_version(cluster_handle)?;
137 let output;
138 if let Some(p) = osd_path {
139 let path = format!("{}", p.display());
140 output = Command::new("ceph-volume")
141 .args(&["simple", "scan", "--stdout", &path])
142 .output()?;
143 } else {
144 output = Command::new("ceph-volume")
145 .args(&["simple", "scan", "--stdout"])
146 .output()?;
147 }
148 let json = String::from_utf8_lossy(&output.stdout);
149 let index: usize = match json.find("{") {
150 Some(i) => i,
151 None => 0,
152 };
153 let json = json.split_at(index);
155 match json_data(&json.1) {
156 Some(jsondata) => Ok(jsondata),
157 _ => Err(RadosError::new("JSON data not found.".to_string())),
158 }
159}