tape: show catalog status in media list
This commit is contained in:
parent
c7926d8e8c
commit
0bf1c314da
@ -58,12 +58,15 @@ pub async fn list_media(pool: Option<String>) -> Result<Vec<MediaListEntry>, Err
|
|||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let status_path = Path::new(TAPE_STATUS_DIR);
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
let catalogs = tokio::task::spawn_blocking(move || {
|
||||||
|
// update online media status
|
||||||
if let Err(err) = update_online_status(status_path) {
|
if let Err(err) = update_online_status(status_path) {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
eprintln!("update online media status failed - using old state");
|
eprintln!("update online media status failed - using old state");
|
||||||
}
|
}
|
||||||
}).await?;
|
// test what catalog files we have
|
||||||
|
MediaCatalog::media_with_catalogs(status_path)
|
||||||
|
}).await??;
|
||||||
|
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
|
||||||
@ -100,12 +103,20 @@ pub async fn list_media(pool: Option<String>) -> Result<Vec<MediaListEntry>, Err
|
|||||||
.unwrap_or_else(|_| set.uuid.to_string())
|
.unwrap_or_else(|_| set.uuid.to_string())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let catalog_ok = if media.media_set_label().is_none() {
|
||||||
|
// Media is empty, we need no catalog
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
catalogs.contains(media.uuid())
|
||||||
|
};
|
||||||
|
|
||||||
list.push(MediaListEntry {
|
list.push(MediaListEntry {
|
||||||
uuid: media.uuid().to_string(),
|
uuid: media.uuid().to_string(),
|
||||||
changer_id: media.changer_id().to_string(),
|
changer_id: media.changer_id().to_string(),
|
||||||
pool: Some(pool_name.to_string()),
|
pool: Some(pool_name.to_string()),
|
||||||
location: media.location().clone(),
|
location: media.location().clone(),
|
||||||
status: *media.status(),
|
status: *media.status(),
|
||||||
|
catalog: catalog_ok,
|
||||||
expired,
|
expired,
|
||||||
media_set_uuid,
|
media_set_uuid,
|
||||||
media_set_name,
|
media_set_name,
|
||||||
@ -131,6 +142,7 @@ pub async fn list_media(pool: Option<String>) -> Result<Vec<MediaListEntry>, Err
|
|||||||
changer_id: media_id.label.changer_id.to_string(),
|
changer_id: media_id.label.changer_id.to_string(),
|
||||||
location,
|
location,
|
||||||
status,
|
status,
|
||||||
|
catalog: true, // empty, so we do not need a catalog
|
||||||
expired: false,
|
expired: false,
|
||||||
media_set_uuid: None,
|
media_set_uuid: None,
|
||||||
media_set_name: None,
|
media_set_name: None,
|
||||||
|
@ -29,6 +29,8 @@ pub struct MediaListEntry {
|
|||||||
pub status: MediaStatus,
|
pub status: MediaStatus,
|
||||||
/// Expired flag
|
/// Expired flag
|
||||||
pub expired: bool,
|
pub expired: bool,
|
||||||
|
/// Catalog status OK
|
||||||
|
pub catalog: bool,
|
||||||
/// Media set name
|
/// Media set name
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub media_set_name: Option<String>,
|
pub media_set_name: Option<String>,
|
||||||
|
@ -104,6 +104,14 @@ async fn list_media(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn catalog_status(value: &Value, _record: &Value) -> Result<String, Error> {
|
||||||
|
let catalog_ok = value.as_bool().unwrap();
|
||||||
|
if catalog_ok {
|
||||||
|
Ok(String::from("ok"))
|
||||||
|
} else {
|
||||||
|
Ok(String::from("missing"))
|
||||||
|
}
|
||||||
|
}
|
||||||
let options = default_table_format_options()
|
let options = default_table_format_options()
|
||||||
.sortby("pool", false)
|
.sortby("pool", false)
|
||||||
.sortby("media-set-uuid", false)
|
.sortby("media-set-uuid", false)
|
||||||
@ -115,6 +123,7 @@ async fn list_media(
|
|||||||
.column(ColumnConfig::new("seq-nr"))
|
.column(ColumnConfig::new("seq-nr"))
|
||||||
.column(ColumnConfig::new("status").renderer(render_status))
|
.column(ColumnConfig::new("status").renderer(render_status))
|
||||||
.column(ColumnConfig::new("location"))
|
.column(ColumnConfig::new("location"))
|
||||||
|
.column(ColumnConfig::new("catalog").renderer(catalog_status))
|
||||||
.column(ColumnConfig::new("uuid"))
|
.column(ColumnConfig::new("uuid"))
|
||||||
.column(ColumnConfig::new("media-set-uuid"))
|
.column(ColumnConfig::new("media-set-uuid"))
|
||||||
;
|
;
|
||||||
|
@ -3,7 +3,7 @@ use std::fs::File;
|
|||||||
use std::io::{Write, Read, BufReader, Seek, SeekFrom};
|
use std::io::{Write, Read, BufReader, Seek, SeekFrom};
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashSet, HashMap};
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use endian_trait::Endian;
|
use endian_trait::Endian;
|
||||||
@ -22,6 +22,7 @@ use proxmox::tools::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
tools::fs::read_subdir,
|
||||||
backup::BackupDir,
|
backup::BackupDir,
|
||||||
tape::{
|
tape::{
|
||||||
MediaId,
|
MediaId,
|
||||||
@ -58,6 +59,22 @@ pub struct MediaCatalog {
|
|||||||
|
|
||||||
impl MediaCatalog {
|
impl MediaCatalog {
|
||||||
|
|
||||||
|
/// List media with catalogs
|
||||||
|
pub fn media_with_catalogs(base_path: &Path) -> Result<HashSet<Uuid>, Error> {
|
||||||
|
let mut catalogs = HashSet::new();
|
||||||
|
|
||||||
|
for entry in read_subdir(libc::AT_FDCWD, base_path)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let name = unsafe { entry.file_name_utf8_unchecked() };
|
||||||
|
if !name.ends_with(".log") { continue; }
|
||||||
|
if let Ok(uuid) = Uuid::parse_str(&name[..(name.len()-4)]) {
|
||||||
|
catalogs.insert(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(catalogs)
|
||||||
|
}
|
||||||
|
|
||||||
/// Test if a catalog exists
|
/// Test if a catalog exists
|
||||||
pub fn exists(base_path: &Path, uuid: &Uuid) -> bool {
|
pub fn exists(base_path: &Path, uuid: &Uuid) -> bool {
|
||||||
let mut path = base_path.to_owned();
|
let mut path = base_path.to_owned();
|
||||||
|
Loading…
Reference in New Issue
Block a user