1 use anyhow
::{bail, Error}
;
4 use proxmox
::api
::{api, Router, RpcEnvironment}
;
9 PROXMOX_CONFIG_DIGEST_SCHEMA
,
11 LINUX_DRIVE_PATH_SCHEMA
,
17 linux_tape_changer_list
,
27 schema
: CHANGER_ID_SCHEMA
,
30 schema
: LINUX_DRIVE_PATH_SCHEMA
,
35 /// Create a new changer device
36 pub fn create_changer(
39 ) -> Result
<(), Error
> {
41 let _lock
= config
::drive
::lock()?
;
43 let (mut config
, _digest
) = config
::drive
::config()?
;
45 let linux_changers
= linux_tape_changer_list();
47 check_drive_path(&linux_changers
, &path
)?
;
49 if config
.sections
.get(&name
).is_some() {
50 bail
!("Entry '{}' already exists", name
);
53 let item
= ScsiTapeChanger
{
58 config
.set_data(&name
, "changer", &item
)?
;
60 config
::drive
::save_config(&config
)?
;
69 schema
: CHANGER_ID_SCHEMA
,
74 type: ScsiTapeChanger
,
78 /// Get tape changer configuration
82 mut rpcenv
: &mut dyn RpcEnvironment
,
83 ) -> Result
<ScsiTapeChanger
, Error
> {
85 let (config
, digest
) = config
::drive
::config()?
;
87 let data
: ScsiTapeChanger
= config
.lookup("changer", &name
)?
;
89 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
99 description
: "The list of configured changers (with config digest).",
102 type: DriveListEntry
,
107 pub fn list_changers(
109 mut rpcenv
: &mut dyn RpcEnvironment
,
110 ) -> Result
<Vec
<DriveListEntry
>, Error
> {
112 let (config
, digest
) = config
::drive
::config()?
;
114 let linux_changers
= linux_tape_changer_list();
116 let changer_list
: Vec
<ScsiTapeChanger
> = config
.convert_to_typed_array("changer")?
;
118 let mut list
= Vec
::new();
120 for changer
in changer_list
{
121 let mut entry
= DriveListEntry
{
123 path
: changer
.path
.clone(),
129 if let Some(info
) = lookup_drive(&linux_changers
, &changer
.path
) {
130 entry
.vendor
= Some(info
.vendor
.clone());
131 entry
.model
= Some(info
.model
.clone());
132 entry
.serial
= Some(info
.serial
.clone());
138 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
146 schema
: CHANGER_ID_SCHEMA
,
149 schema
: LINUX_DRIVE_PATH_SCHEMA
,
153 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
159 /// Update a tape changer configuration
160 pub fn update_changer(
162 path
: Option
<String
>,
163 digest
: Option
<String
>,
165 ) -> Result
<(), Error
> {
167 let _lock
= config
::drive
::lock()?
;
169 let (mut config
, expected_digest
) = config
::drive
::config()?
;
171 if let Some(ref digest
) = digest
{
172 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
173 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
176 let mut data
: ScsiTapeChanger
= config
.lookup("changer", &name
)?
;
178 if let Some(path
) = path
{
179 let changers
= linux_tape_changer_list();
180 check_drive_path(&changers
, &path
)?
;
184 config
.set_data(&name
, "changer", &data
)?
;
186 config
::drive
::save_config(&config
)?
;
195 schema
: CHANGER_ID_SCHEMA
,
200 /// Delete a tape changer configuration
201 pub fn delete_changer(name
: String
, _param
: Value
) -> Result
<(), Error
> {
203 let _lock
= config
::drive
::lock()?
;
205 let (mut config
, _digest
) = config
::drive
::config()?
;
207 match config
.sections
.get(&name
) {
208 Some((section_type
, _
)) => {
209 if section_type
!= "changer" {
210 bail
!("Entry '{}' exists, but is not a changer device", name
);
212 config
.sections
.remove(&name
);
214 None
=> bail
!("Delete changer '{}' failed - no such entry", name
),
217 config
::drive
::save_config(&config
)?
;
227 description
: "The list of autodetected tape changers.",
230 type: TapeDeviceInfo
,
234 /// Scan for SCSI tape changers
235 pub fn scan_changers(_param
: Value
) -> Result
<Vec
<TapeDeviceInfo
>, Error
> {
237 let list
= linux_tape_changer_list();
242 pub const SCAN_CHANGERS
: Router
= Router
::new()
243 .get(&API_METHOD_SCAN_CHANGERS
);
246 const ITEM_ROUTER
: Router
= Router
::new()
247 .get(&API_METHOD_GET_CONFIG
)
248 .put(&API_METHOD_UPDATE_CHANGER
)
249 .delete(&API_METHOD_DELETE_CHANGER
);
252 pub const ROUTER
: Router
= Router
::new()
253 .get(&API_METHOD_LIST_CHANGERS
)
254 .post(&API_METHOD_CREATE_CHANGER
)
255 .match_all("name", &ITEM_ROUTER
);