tape: media_list API - allow to update online status for a single changer
This commit is contained in:
		@ -20,6 +20,7 @@ use crate::{
 | 
			
		||||
        MEDIA_LABEL_SCHEMA,
 | 
			
		||||
        MEDIA_UUID_SCHEMA,
 | 
			
		||||
        MEDIA_SET_UUID_SCHEMA,
 | 
			
		||||
        CHANGER_NAME_SCHEMA,
 | 
			
		||||
        MediaPoolConfig,
 | 
			
		||||
        MediaListEntry,
 | 
			
		||||
        MediaStatus,
 | 
			
		||||
@ -50,6 +51,11 @@ use crate::{
 | 
			
		||||
                optional: true,
 | 
			
		||||
                default: true,
 | 
			
		||||
            },
 | 
			
		||||
            "update-status-changer": {
 | 
			
		||||
                // only update status for a single changer
 | 
			
		||||
                schema: CHANGER_NAME_SCHEMA,
 | 
			
		||||
                optional: true,
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    returns: {
 | 
			
		||||
@ -64,6 +70,7 @@ use crate::{
 | 
			
		||||
pub async fn list_media(
 | 
			
		||||
    pool: Option<String>,
 | 
			
		||||
    update_status: bool,
 | 
			
		||||
    update_status_changer: Option<String>,
 | 
			
		||||
) -> Result<Vec<MediaListEntry>, Error> {
 | 
			
		||||
 | 
			
		||||
    let (config, _digest) = config::media_pool::config()?;
 | 
			
		||||
@ -73,7 +80,7 @@ pub async fn list_media(
 | 
			
		||||
    let catalogs = tokio::task::spawn_blocking(move || {
 | 
			
		||||
        if update_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!("update online media status failed - using old state");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -15,11 +15,13 @@ use proxmox_backup::{
 | 
			
		||||
        self,
 | 
			
		||||
        types::{
 | 
			
		||||
            MEDIA_POOL_NAME_SCHEMA,
 | 
			
		||||
            CHANGER_NAME_SCHEMA,
 | 
			
		||||
            MediaStatus,
 | 
			
		||||
            MediaListEntry,
 | 
			
		||||
        },
 | 
			
		||||
        tape::media::MediaContentListFilter,
 | 
			
		||||
    },
 | 
			
		||||
    config::drive::complete_changer_name,
 | 
			
		||||
    tape::{
 | 
			
		||||
        complete_media_label_text,
 | 
			
		||||
        complete_media_uuid,
 | 
			
		||||
@ -37,6 +39,7 @@ pub fn media_commands() -> CommandLineInterface {
 | 
			
		||||
            "list",
 | 
			
		||||
            CliCommand::new(&API_METHOD_LIST_MEDIA)
 | 
			
		||||
                .completion_cb("pool", complete_pool_name)
 | 
			
		||||
                .completion_cb("update-status-changer", complete_changer_name)
 | 
			
		||||
        )
 | 
			
		||||
        .insert(
 | 
			
		||||
            "destroy",
 | 
			
		||||
@ -64,6 +67,17 @@ pub fn media_commands() -> CommandLineInterface {
 | 
			
		||||
                schema: MEDIA_POOL_NAME_SCHEMA,
 | 
			
		||||
                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": {
 | 
			
		||||
                schema: OUTPUT_FORMAT,
 | 
			
		||||
                optional: true,
 | 
			
		||||
 | 
			
		||||
@ -122,8 +122,8 @@ pub fn mtx_status_to_online_set(status: &MtxStatus, inventory: &Inventory) -> Ha
 | 
			
		||||
 | 
			
		||||
/// Update online media status
 | 
			
		||||
///
 | 
			
		||||
/// Simply ask all changer devices.
 | 
			
		||||
pub fn update_online_status(state_path: &Path) -> Result<OnlineStatusMap, Error> {
 | 
			
		||||
/// For a single 'changer', or else simply ask all changer devices.
 | 
			
		||||
pub fn update_online_status(state_path: &Path, changer: Option<&str>) -> Result<OnlineStatusMap, Error> {
 | 
			
		||||
 | 
			
		||||
    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)?;
 | 
			
		||||
 | 
			
		||||
    for mut changer in changers {
 | 
			
		||||
        let status = match changer.status() {
 | 
			
		||||
    let mut found_changer = false;
 | 
			
		||||
 | 
			
		||||
    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,
 | 
			
		||||
            Err(err) => {
 | 
			
		||||
                eprintln!("unable to get changer '{}' status - {}", changer.name, err);
 | 
			
		||||
                eprintln!("unable to get changer '{}' status - {}", changer_config.name, err);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        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")?;
 | 
			
		||||
    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() {
 | 
			
		||||
            Ok(media_list) => media_list,
 | 
			
		||||
            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)?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if let Some(changer) = changer {
 | 
			
		||||
        if !found_changer {
 | 
			
		||||
            bail!("update_online_status failed - no such changer '{}'", changer);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inventory.update_online_status(&map)?;
 | 
			
		||||
 | 
			
		||||
    Ok(map)
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user