5 use pbs_datastore
::{task_log, task_warn}
;
6 use pbs_datastore
::backup_info
::BackupInfo
;
7 use pbs_datastore
::prune
::compute_prune_info
;
8 use pbs_api_types
::{Authid, PRIV_DATASTORE_MODIFY, PruneOptions}
;
9 use pbs_config
::CachedUserInfo
;
13 server
::jobstate
::Job
,
17 pub fn prune_datastore(
18 worker
: Arc
<WorkerTask
>,
20 prune_options
: PruneOptions
,
22 datastore
: Arc
<DataStore
>,
24 ) -> Result
<(), Error
> {
25 task_log
!(worker
, "Starting datastore prune on store \"{}\"", store
);
28 task_log
!(worker
, "(dry test run)");
31 let keep_all
= !pbs_datastore
::prune
::keeps_something(&prune_options
);
34 task_log
!(worker
, "No prune selection - keeping all files.");
38 "retention options: {}",
39 pbs_datastore
::prune
::cli_options_string(&prune_options
)
43 let user_info
= CachedUserInfo
::new()?
;
44 let privs
= user_info
.lookup_privs(&auth_id
, &["datastore", store
]);
45 let has_privs
= privs
& PRIV_DATASTORE_MODIFY
!= 0;
47 let base_path
= datastore
.base_path();
49 let groups
= BackupInfo
::list_backup_groups(&base_path
)?
;
51 let list
= group
.list_backups(&base_path
)?
;
53 if !has_privs
&& !datastore
.owns_backup(&group
, &auth_id
)?
{
57 let mut prune_info
= compute_prune_info(list
, &prune_options
)?
;
58 prune_info
.reverse(); // delete older snapshots first
62 "Starting prune on store \"{}\" group \"{}/{}\"",
68 for (info
, mut keep
) in prune_info
{
69 if keep_all { keep = true; }
73 if keep { "keep" }
else { "remove" }
,
76 info
.backup_dir
.backup_time_string()
78 if !keep
&& !dry_run
{
79 if let Err(err
) = datastore
.remove_backup_dir(&info
.backup_dir
, false) {
82 "failed to remove dir {:?}: {}",
83 info
.backup_dir
.relative_path(),
96 prune_options
: PruneOptions
,
99 schedule
: Option
<String
>,
100 ) -> Result
<String
, Error
> {
101 let datastore
= DataStore
::lookup_datastore(&store
)?
;
103 let worker_type
= job
.jobtype().to_string();
104 let auth_id
= auth_id
.clone();
105 let upid_str
= WorkerTask
::new_thread(
107 Some(job
.jobname().to_string()),
111 job
.start(&worker
.upid().to_string())?
;
113 if let Some(event_str
) = schedule
{
114 task_log
!(worker
, "task triggered by schedule '{}'", event_str
);
117 let result
= prune_datastore(worker
.clone(), auth_id
, prune_options
, &store
, datastore
, false);
119 let status
= worker
.create_state(&result
);
121 if let Err(err
) = job
.finish(status
) {
123 "could not finish job state for {}: {}",
124 job
.jobtype().to_string(),