api2/tape/backup: add 'force-media-set' parameter to manual backup
so that a user can force a new media set, e.g. if he uses the allocation policy 'continue', but wants to manually start a new media-set. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
10f788b7eb
commit
e953029e8f
@ -226,6 +226,7 @@ pub fn do_tape_backup_job(
|
|||||||
&setup,
|
&setup,
|
||||||
email.clone(),
|
email.clone(),
|
||||||
&mut summary,
|
&mut summary,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -312,6 +313,12 @@ pub fn run_tape_backup_job(
|
|||||||
type: TapeBackupJobSetup,
|
type: TapeBackupJobSetup,
|
||||||
flatten: true,
|
flatten: true,
|
||||||
},
|
},
|
||||||
|
"force-media-set": {
|
||||||
|
description: "Ignore the allocation policy and start a new media-set.",
|
||||||
|
optional: true,
|
||||||
|
type: bool,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
returns: {
|
returns: {
|
||||||
@ -327,6 +334,7 @@ pub fn run_tape_backup_job(
|
|||||||
/// Backup datastore to tape media pool
|
/// Backup datastore to tape media pool
|
||||||
pub fn backup(
|
pub fn backup(
|
||||||
setup: TapeBackupJobSetup,
|
setup: TapeBackupJobSetup,
|
||||||
|
force_media_set: bool,
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
rpcenv: &mut dyn RpcEnvironment,
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
@ -373,6 +381,7 @@ pub fn backup(
|
|||||||
&setup,
|
&setup,
|
||||||
email.clone(),
|
email.clone(),
|
||||||
&mut summary,
|
&mut summary,
|
||||||
|
force_media_set,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(email) = email {
|
if let Some(email) = email {
|
||||||
@ -403,6 +412,7 @@ fn backup_worker(
|
|||||||
setup: &TapeBackupJobSetup,
|
setup: &TapeBackupJobSetup,
|
||||||
email: Option<String>,
|
email: Option<String>,
|
||||||
summary: &mut TapeBackupJobSummary,
|
summary: &mut TapeBackupJobSummary,
|
||||||
|
force_media_set: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let status_path = Path::new(TAPE_STATUS_DIR);
|
||||||
@ -413,7 +423,13 @@ fn backup_worker(
|
|||||||
|
|
||||||
let pool = MediaPool::with_config(status_path, &pool_config, changer_name, false)?;
|
let pool = MediaPool::with_config(status_path, &pool_config, changer_name, false)?;
|
||||||
|
|
||||||
let mut pool_writer = PoolWriter::new(pool, &setup.drive, worker, email)?;
|
let mut pool_writer = PoolWriter::new(
|
||||||
|
pool,
|
||||||
|
&setup.drive,
|
||||||
|
worker,
|
||||||
|
email,
|
||||||
|
force_media_set
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut group_list = BackupInfo::list_backup_groups(&datastore.base_path())?;
|
let mut group_list = BackupInfo::list_backup_groups(&datastore.base_path())?;
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ pub async fn list_media(
|
|||||||
// Call start_write_session, so that we show the same status a
|
// Call start_write_session, so that we show the same status a
|
||||||
// backup job would see.
|
// backup job would see.
|
||||||
pool.force_media_availability();
|
pool.force_media_availability();
|
||||||
pool.start_write_session(current_time)?;
|
pool.start_write_session(current_time, false)?;
|
||||||
|
|
||||||
for media in pool.list_media() {
|
for media in pool.list_media() {
|
||||||
let expired = pool.media_is_expired(&media, current_time);
|
let expired = pool.media_is_expired(&media, current_time);
|
||||||
|
@ -258,7 +258,7 @@ impl MediaPool {
|
|||||||
/// Make sure the current media set is usable for writing
|
/// Make sure the current media set is usable for writing
|
||||||
///
|
///
|
||||||
/// If not, starts a new media set. Also creates a new
|
/// If not, starts a new media set. Also creates a new
|
||||||
/// set if media_set_policy implies it.
|
/// set if media_set_policy implies it, or if 'force' is true.
|
||||||
///
|
///
|
||||||
/// Note: We also call this in list_media to compute correct media
|
/// Note: We also call this in list_media to compute correct media
|
||||||
/// status, so this must not change persistent/saved state.
|
/// status, so this must not change persistent/saved state.
|
||||||
@ -267,6 +267,7 @@ impl MediaPool {
|
|||||||
pub fn start_write_session(
|
pub fn start_write_session(
|
||||||
&mut self,
|
&mut self,
|
||||||
current_time: i64,
|
current_time: i64,
|
||||||
|
force: bool,
|
||||||
) -> Result<Option<String>, Error> {
|
) -> Result<Option<String>, Error> {
|
||||||
|
|
||||||
let _pool_lock = if self.no_media_set_locking {
|
let _pool_lock = if self.no_media_set_locking {
|
||||||
@ -277,11 +278,15 @@ impl MediaPool {
|
|||||||
|
|
||||||
self.inventory.reload()?;
|
self.inventory.reload()?;
|
||||||
|
|
||||||
let mut create_new_set = match self.current_set_usable() {
|
let mut create_new_set = if force {
|
||||||
Err(err) => {
|
Some(String::from("forced"))
|
||||||
Some(err.to_string())
|
} else {
|
||||||
}
|
match self.current_set_usable() {
|
||||||
Ok(_) => None,
|
Err(err) => {
|
||||||
|
Some(err.to_string())
|
||||||
|
}
|
||||||
|
Ok(_) => None,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if create_new_set.is_none() {
|
if create_new_set.is_none() {
|
||||||
|
@ -71,11 +71,12 @@ impl PoolWriter {
|
|||||||
drive_name: &str,
|
drive_name: &str,
|
||||||
worker: &WorkerTask,
|
worker: &WorkerTask,
|
||||||
notify_email: Option<String>,
|
notify_email: Option<String>,
|
||||||
|
force_media_set: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
|
||||||
let current_time = proxmox::tools::time::epoch_i64();
|
let current_time = proxmox::tools::time::epoch_i64();
|
||||||
|
|
||||||
let new_media_set_reason = pool.start_write_session(current_time)?;
|
let new_media_set_reason = pool.start_write_session(current_time, force_media_set)?;
|
||||||
if let Some(reason) = new_media_set_reason {
|
if let Some(reason) = new_media_set_reason {
|
||||||
task_log!(
|
task_log!(
|
||||||
worker,
|
worker,
|
||||||
|
Loading…
Reference in New Issue
Block a user