tape: media_list API - allow to update online status for a single changer

This commit is contained in:
Dietmar Maurer 2021-02-18 10:59:33 +01:00
parent 65535670f9
commit 9bbd83b1f2
3 changed files with 49 additions and 7 deletions

View File

@ -20,6 +20,7 @@ use crate::{
MEDIA_LABEL_SCHEMA, MEDIA_LABEL_SCHEMA,
MEDIA_UUID_SCHEMA, MEDIA_UUID_SCHEMA,
MEDIA_SET_UUID_SCHEMA, MEDIA_SET_UUID_SCHEMA,
CHANGER_NAME_SCHEMA,
MediaPoolConfig, MediaPoolConfig,
MediaListEntry, MediaListEntry,
MediaStatus, MediaStatus,
@ -50,6 +51,11 @@ use crate::{
optional: true, optional: true,
default: true, default: true,
}, },
"update-status-changer": {
// only update status for a single changer
schema: CHANGER_NAME_SCHEMA,
optional: true,
},
}, },
}, },
returns: { returns: {
@ -64,6 +70,7 @@ use crate::{
pub async fn list_media( pub async fn list_media(
pool: Option<String>, pool: Option<String>,
update_status: bool, update_status: bool,
update_status_changer: Option<String>,
) -> Result<Vec<MediaListEntry>, Error> { ) -> Result<Vec<MediaListEntry>, Error> {
let (config, _digest) = config::media_pool::config()?; let (config, _digest) = config::media_pool::config()?;
@ -73,7 +80,7 @@ pub async fn list_media(
let catalogs = tokio::task::spawn_blocking(move || { let catalogs = tokio::task::spawn_blocking(move || {
if update_status { if update_status {
// update online media status // update online media status
if let Err(err) = update_online_status(status_path) { if let Err(err) = update_online_status(status_path, update_status_changer.as_deref()) {
eprintln!("{}", err); eprintln!("{}", err);
eprintln!("update online media status failed - using old state"); eprintln!("update online media status failed - using old state");
} }

View File

@ -15,11 +15,13 @@ use proxmox_backup::{
self, self,
types::{ types::{
MEDIA_POOL_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
CHANGER_NAME_SCHEMA,
MediaStatus, MediaStatus,
MediaListEntry, MediaListEntry,
}, },
tape::media::MediaContentListFilter, tape::media::MediaContentListFilter,
}, },
config::drive::complete_changer_name,
tape::{ tape::{
complete_media_label_text, complete_media_label_text,
complete_media_uuid, complete_media_uuid,
@ -37,6 +39,7 @@ pub fn media_commands() -> CommandLineInterface {
"list", "list",
CliCommand::new(&API_METHOD_LIST_MEDIA) CliCommand::new(&API_METHOD_LIST_MEDIA)
.completion_cb("pool", complete_pool_name) .completion_cb("pool", complete_pool_name)
.completion_cb("update-status-changer", complete_changer_name)
) )
.insert( .insert(
"destroy", "destroy",
@ -64,6 +67,17 @@ pub fn media_commands() -> CommandLineInterface {
schema: MEDIA_POOL_NAME_SCHEMA, schema: MEDIA_POOL_NAME_SCHEMA,
optional: true, optional: true,
}, },
"update-status": {
description: "Try to update tape library status (check what tapes are online).",
type: bool,
optional: true,
default: true,
},
"update-status-changer": {
// only update status for a single changer
schema: CHANGER_NAME_SCHEMA,
optional: true,
},
"output-format": { "output-format": {
schema: OUTPUT_FORMAT, schema: OUTPUT_FORMAT,
optional: true, optional: true,

View File

@ -122,8 +122,8 @@ pub fn mtx_status_to_online_set(status: &MtxStatus, inventory: &Inventory) -> Ha
/// Update online media status /// Update online media status
/// ///
/// Simply ask all changer devices. /// For a single 'changer', or else simply ask all changer devices.
pub fn update_online_status(state_path: &Path) -> Result<OnlineStatusMap, Error> { pub fn update_online_status(state_path: &Path, changer: Option<&str>) -> Result<OnlineStatusMap, Error> {
let (config, _digest) = crate::config::drive::config()?; let (config, _digest) = crate::config::drive::config()?;
@ -133,21 +133,36 @@ pub fn update_online_status(state_path: &Path) -> Result<OnlineStatusMap, Error>
let mut map = OnlineStatusMap::new(&config)?; let mut map = OnlineStatusMap::new(&config)?;
for mut changer in changers { let mut found_changer = false;
let status = match changer.status() {
for mut changer_config in changers {
if let Some(changer) = changer {
if changer != &changer_config.name {
continue;
}
found_changer = true;
}
let status = match changer_config.status() {
Ok(status) => status, Ok(status) => status,
Err(err) => { Err(err) => {
eprintln!("unable to get changer '{}' status - {}", changer.name, err); eprintln!("unable to get changer '{}' status - {}", changer_config.name, err);
continue; continue;
} }
}; };
let online_set = mtx_status_to_online_set(&status, &inventory); let online_set = mtx_status_to_online_set(&status, &inventory);
map.update_online_status(&changer.name, online_set)?; map.update_online_status(&changer_config.name, online_set)?;
} }
let vtapes: Vec<VirtualTapeDrive> = config.convert_to_typed_array("virtual")?; let vtapes: Vec<VirtualTapeDrive> = config.convert_to_typed_array("virtual")?;
for mut vtape in vtapes { for mut vtape in vtapes {
if let Some(changer) = changer {
if changer != &vtape.name {
continue;
}
found_changer = true;
}
let media_list = match vtape.online_media_label_texts() { let media_list = match vtape.online_media_label_texts() {
Ok(media_list) => media_list, Ok(media_list) => media_list,
Err(err) => { Err(err) => {
@ -165,6 +180,12 @@ pub fn update_online_status(state_path: &Path) -> Result<OnlineStatusMap, Error>
map.update_online_status(&vtape.name, online_set)?; map.update_online_status(&vtape.name, online_set)?;
} }
if let Some(changer) = changer {
if !found_changer {
bail!("update_online_status failed - no such changer '{}'", changer);
}
}
inventory.update_online_status(&map)?; inventory.update_online_status(&map)?;
Ok(map) Ok(map)