Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
git_borg_linker
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
LBMC
Hub
git_borg_linker
Commits
6d861d98
Verified
Commit
6d861d98
authored
2 years ago
by
nfontrod
Browse files
Options
Downloads
Patches
Plain Diff
src/configt.rs src/prune.rs src/main.rs: add configuration to ease pruning
parent
c9c161e2
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/configt.rs
+418
-0
418 additions, 0 deletions
src/configt.rs
src/main.rs
+44
-3
44 additions, 3 deletions
src/main.rs
src/prune.rs
+25
-0
25 additions, 0 deletions
src/prune.rs
with
487 additions
and
3 deletions
src/configt.rs
0 → 100644
+
418
−
0
View file @
6d861d98
use
crate
::
commit
;
use
crate
::
prune
::{
new_prune
,
prune_launcher
};
use
clap
::
Args
;
use
colored
::
Colorize
;
use
regex
::
Regex
;
use
serde_derive
::{
Deserialize
,
Serialize
};
use
std
::{
path
::
PathBuf
,
process
::
exit
};
use
toml
::{
self
,
Value
};
#[derive(Debug,
Args)]
pub
(
crate
)
struct
PartialPrune
{
/// Do not change the repository
#[clap(
short
=
'n'
,
long
=
"dry-run"
,
takes_value
=
false
,
help_heading
=
"Filtering options"
,
display_order
=
1
)]
pub
(
crate
)
dry_run
:
bool
,
/// Output verbose list of archive
#[clap(
long
=
"--list"
,
takes_value
=
false
,
help_heading
=
"Filtering options"
,
display_order
=
2
)]
pub
(
crate
)
list
:
bool
,
/// Print statistics for the deleted archive
#[clap(
short
=
's'
,
long
=
"stats"
,
takes_value
=
false
,
help_heading
=
"Filtering options"
,
display_order
=
3
)]
pub
(
crate
)
stats
:
bool
,
/// Force deletion of corrupted archives, use `--force --force` in case `--force` does not work.
#[clap(
long,
parse(from_occurrences),
takes_value
=
false
,
help_heading
=
"Filtering options"
,
display_order
=
4
)]
pub
(
crate
)
force
:
usize
,
}
// ================================ toml structure of borg config
/// Structure containing the global definition of the borg config file
#[derive(Debug,
Deserialize,
Serialize,
Clone)]
pub
struct
Config
{
repository
:
Repository
,
gblk_prune
:
Option
<
GblkConfig
>
,
}
/// Structure that store the current borg configuration for the project
#[derive(Debug,
Deserialize,
Serialize,
Clone)]
struct
Repository
{
version
:
Value
,
segments_per_dir
:
usize
,
max_segment_size
:
usize
,
append_only
:
usize
,
storage_quota
:
usize
,
additional_free_space
:
usize
,
id
:
String
,
}
/// Structure corresponding to the gblk prune config to automatically use
/// inside a project
#[derive(Debug,
Deserialize,
Serialize,
Clone)]
pub
struct
GblkConfig
{
pub
save_space
:
Option
<
bool
>
,
pub
keep_within
:
Option
<
String
>
,
pub
keep_last
:
Option
<
usize
>
,
pub
keep_minutely
:
Option
<
usize
>
,
pub
keep_hourly
:
Option
<
usize
>
,
pub
keep_daily
:
Option
<
usize
>
,
pub
keep_weekly
:
Option
<
usize
>
,
pub
keep_monthly
:
Option
<
usize
>
,
pub
keep_yearly
:
Option
<
usize
>
,
pub
prefix
:
Option
<
String
>
,
pub
glob_archives
:
Option
<
String
>
,
}
impl
GblkConfig
{
fn
empty
(
&
self
)
->
bool
{
if
self
.save_space
!=
None
{
return
false
;
};
if
self
.keep_within
!=
None
{
return
false
;
};
if
self
.keep_last
!=
None
{
return
false
;
};
if
self
.keep_minutely
!=
None
{
return
false
;
};
if
self
.keep_hourly
!=
None
{
return
false
;
};
if
self
.keep_daily
!=
None
{
return
false
;
};
if
self
.keep_weekly
!=
None
{
return
false
;
};
if
self
.keep_monthly
!=
None
{
return
false
;
};
if
self
.keep_yearly
!=
None
{
return
false
;
};
if
self
.prefix
!=
None
{
return
false
;
};
if
self
.glob_archives
!=
None
{
return
false
;
};
true
}
}
// =================== Functions
/// Get the config file inside borg folder
/// # Return
/// A pathbuf variable containing the location of borg config file for the
/// current project
fn
get_borgconfig
()
->
PathBuf
{
let
(
mut
config_path
,
_
)
=
commit
::
check_path
();
config_path
.push
(
"config"
);
if
!
config_path
.is_file
()
{
eprintln!
(
"{} not found !"
,
config_path
.to_str
()
.unwrap
());
exit
(
1
);
}
config_path
}
fn
parse_toml
()
->
Config
{
let
config_file
=
get_borgconfig
();
let
rcontent
=
std
::
fs
::
read_to_string
(
&
config_file
);
let
content
=
match
rcontent
{
Err
(
e
)
=>
{
eprintln!
(
"Unable to read {} - {}"
,
&
config_file
.to_str
()
.unwrap
(),
e
);
exit
(
101
);
}
Ok
(
s
)
=>
s
,
};
let
re
=
Regex
::
new
(
"id = (?P<first>[0-9a-z]+)
\\
W"
)
.unwrap
();
let
nc
=
re
.replace
(
&
content
,
"id = '$first'"
);
let
config_str
:
Config
=
toml
::
from_str
(
&
nc
)
.unwrap
();
config_str
}
/// Function that show the current gblk config of the borg folder
pub
fn
show
()
->
()
{
let
config
=
parse_toml
();
let
gblk_config
:
GblkConfig
=
match
config
.gblk_prune
{
Some
(
data
)
=>
data
,
None
=>
{
println!
(
"{}"
,
"No configuration defined for this project"
.yellow
());
exit
(
0
)
}
};
let
gblk_str
=
toml
::
to_string_pretty
(
&
gblk_config
)
.unwrap
();
println!
(
"{}"
,
gblk_str
);
}
/// Function that update the current gblk config file for the project folder
/// # Arguments
/// - `key` : The key to update
/// - `value`: The value of the key to update
/// # Return
/// The updated prune keys
fn
update_val
(
input
:
&
mut
GblkConfig
,
key
:
&
str
,
value
:
&
str
)
->
()
{
match
key
{
"save_space"
|
"save-space"
=>
{
input
.save_space
=
Some
(
str
::
parse
::
<
bool
>
(
value
)
.unwrap
());
}
"keep_within"
|
"keep-within"
=>
{
input
.keep_within
=
Some
(
value
.to_owned
());
}
"keep_last"
|
"keep-last"
=>
{
input
.keep_last
=
Some
(
str
::
parse
::
<
usize
>
(
value
)
.unwrap
());
}
"keep_minutely"
|
"keep-minutely"
=>
{
input
.keep_minutely
=
Some
(
str
::
parse
::
<
usize
>
(
value
)
.unwrap
());
}
"keep_hourly"
|
"keep-hourly"
=>
{
input
.keep_hourly
=
Some
(
str
::
parse
::
<
usize
>
(
value
)
.unwrap
());
}
"keep_daily"
|
"keep-daily"
=>
{
input
.keep_daily
=
Some
(
str
::
parse
::
<
usize
>
(
value
)
.unwrap
());
}
"keep_weekly"
|
"keep-weekly"
=>
{
input
.keep_weekly
=
Some
(
str
::
parse
::
<
usize
>
(
value
)
.unwrap
());
}
"keep_monthly"
|
"keep-monthly"
=>
{
input
.keep_monthly
=
Some
(
str
::
parse
::
<
usize
>
(
value
)
.unwrap
());
}
"keep_yearly"
|
"keep-yearly"
=>
{
input
.keep_yearly
=
Some
(
str
::
parse
::
<
usize
>
(
value
)
.unwrap
());
}
"prefix"
=>
{
input
.prefix
=
Some
(
value
.to_owned
());
}
"glob_archives"
|
"glob-archives"
=>
{
input
.glob_archives
=
Some
(
value
.to_owned
());
}
&
_
=>
{
eprintln!
(
"{} {} '{}' {}
\n
{}
\n
- {}
\n
- {}"
,
"error:"
.red
(),
"The key"
,
key
,
"doesn't exist !"
,
"choose from:"
,
"keep_within, keep_last, keep_minutely, keep_hourly, keep_daily"
.blue
(),
"keep_weekly, keep_monthly, keep_yearly, prefix, glob_archives, save_space"
.blue
()
);
exit
(
1
);
}
}
}
/// Function that checks if the parameter input param is already defined
/// # Description:
/// If input_param is already defined, returns None but if not, return an error
/// # Arguments:
/// - input_param: A parameter of the gblk config structure
/// - key: The key to remove
/// # Return
/// None if input_param is defined, error else
fn
check_and_warn
<
T
>
(
input_param
:
&
Option
<
T
>
,
key
:
&
str
)
->
Option
<
T
>
{
match
input_param
{
None
=>
{
eprintln!
(
"{} {} {} {}"
,
"error:"
.red
(),
"The key"
,
key
,
"is not defined !"
);
exit
(
103
);
}
Some
(
_
)
=>
None
,
}
}
/// Function that remove a key from the current gblk config file for the project folder
/// # Arguments
/// - `key` : The key to remove
/// # Return
/// The updated prune keys
fn
remove_val
(
input
:
&
mut
GblkConfig
,
key
:
&
str
)
->
()
{
match
key
{
"save_space"
|
"save-space"
=>
{
input
.save_space
=
check_and_warn
(
&
input
.save_space
,
&
key
);
}
"keep_within"
|
"keep-within"
=>
{
input
.keep_within
=
check_and_warn
(
&
input
.keep_within
,
&
key
);
}
"keep_last"
|
"keep-last"
=>
{
input
.keep_last
=
check_and_warn
(
&
input
.keep_last
,
&
key
);
}
"keep_minutely"
|
"keep-minutely"
=>
{
input
.keep_minutely
=
check_and_warn
(
&
input
.keep_minutely
,
&
key
);
}
"keep_hourly"
|
"keep-hourly"
=>
{
input
.keep_hourly
=
check_and_warn
(
&
input
.keep_hourly
,
&
key
);
}
"keep_daily"
|
"keep-daily"
=>
{
input
.keep_daily
=
check_and_warn
(
&
input
.keep_daily
,
&
key
);
}
"keep_weekly"
|
"keep-weekly"
=>
{
input
.keep_weekly
=
check_and_warn
(
&
input
.keep_weekly
,
&
key
);
}
"keep_monthly"
|
"keep-monthly"
=>
{
input
.keep_monthly
=
check_and_warn
(
&
input
.keep_monthly
,
&
key
);
}
"keep_yearly"
|
"keep-yearly"
=>
{
input
.keep_yearly
=
check_and_warn
(
&
input
.keep_yearly
,
&
key
);
}
"prefix"
=>
{
input
.prefix
=
check_and_warn
(
&
input
.prefix
,
&
key
);
}
"glob_archives"
|
"glob-archives"
=>
{
input
.glob_archives
=
check_and_warn
(
&
input
.glob_archives
,
&
key
);
}
&
_
=>
{
eprintln!
(
"{} {} '{}' {}
\n
{}
\n
- {}
\n
- {}"
,
"error:"
.red
(),
"The key"
,
key
,
"doesn't exist !"
,
"choose from:"
,
"keep_within, keep_last, keep_minutely, keep_hourly, keep_daily"
.blue
(),
"keep_weekly, keep_monthly, keep_yearly, prefix, glob_archives, save_space"
.blue
()
);
exit
(
1
);
}
}
}
/// Get the object conrresponding to gblk prune config
/// # Arguments
/// - full_config: The entire configuration file
/// # Return
/// The configuration for gblk prune object
fn
get_gblkconfig
(
full_config
:
&
Config
)
->
GblkConfig
{
let
gblk_config
:
GblkConfig
=
match
&
full_config
.gblk_prune
{
Some
(
data
)
=>
data
.clone
(),
None
=>
GblkConfig
{
save_space
:
None
,
keep_within
:
None
,
keep_last
:
None
,
keep_minutely
:
None
,
keep_hourly
:
None
,
keep_daily
:
None
,
keep_weekly
:
None
,
keep_monthly
:
None
,
keep_yearly
:
None
,
prefix
:
None
,
glob_archives
:
None
,
},
};
gblk_config
}
/// Function that turn toml into string
/// # Argument
/// - config: The full toml file parsed
/// # Return
/// The string corresponding to toml file
fn
toml_to_string
(
config
:
&
Config
)
->
String
{
let
gblk_str
=
toml
::
to_string_pretty
(
&
config
)
.unwrap
();
let
re
=
Regex
::
new
(
"id = '(?P<first>[0-9a-z]+)'"
)
.unwrap
();
let
nc
=
re
.replace
(
&
gblk_str
,
"id = $first"
)
.to_string
();
nc
}
/// Function that update the current gblk config file for the project folder
/// # Arguments
/// - `key` : The key to update
/// - `value`: The value of the key to update
pub
fn
update_config
(
key
:
&
str
,
value
:
&
str
)
->
()
{
let
mut
config
=
parse_toml
();
let
mut
gblk_config
:
GblkConfig
=
get_gblkconfig
(
&
config
);
update_val
(
&
mut
gblk_config
,
key
,
value
);
config
.gblk_prune
=
Some
(
gblk_config
);
let
gblk_str
=
toml_to_string
(
&
config
);
let
config_file
=
get_borgconfig
();
match
std
::
fs
::
write
(
&
config_file
,
gblk_str
)
{
Err
(
_
)
=>
{
eprintln!
(
"{} {} {} {}"
,
"error:"
.red
(),
"Unable to write the config file"
,
config_file
.to_str
()
.unwrap
(),
"!"
);
exit
(
102
);
}
Ok
(
_
)
=>
(),
};
}
/// Function that remove the current gblk config file for the project folder
/// for a given arguments
/// # Arguments
/// - `key` : The key to update
pub
fn
remove_config
(
key
:
&
str
)
->
()
{
let
mut
config
=
parse_toml
();
let
mut
gblk_config
:
GblkConfig
=
get_gblkconfig
(
&
config
);
remove_val
(
&
mut
gblk_config
,
key
);
config
.gblk_prune
=
if
gblk_config
.empty
()
{
None
}
else
{
Some
(
gblk_config
)
};
let
gblk_str
=
toml_to_string
(
&
config
);
let
config_file
=
get_borgconfig
();
match
std
::
fs
::
write
(
&
config_file
,
gblk_str
)
{
Err
(
_
)
=>
{
eprintln!
(
"{} {} {} {}"
,
"error:"
.red
(),
"Unable to write the config file"
,
config_file
.to_str
()
.unwrap
(),
"!"
);
exit
(
102
);
}
Ok
(
_
)
=>
(),
};
}
/// Execute a prune based on gblk configuration
/// # Arguments
/// - config_prune: contains partial configuration for prune that cannot be
/// used in the configuration file
pub
(
crate
)
fn
launch_config_prune
(
config_prune
:
PartialPrune
)
{
let
config
=
parse_toml
();
let
gblk_config
:
GblkConfig
=
get_gblkconfig
(
&
config
);
if
gblk_config
.empty
()
{
eprintln!
(
"{} No configuration defined for pruning!"
,
"error:"
.red
()
);
exit
(
104
);
}
let
prune_obj
=
new_prune
(
gblk_config
,
config_prune
);
prune_launcher
(
prune_obj
);
}
This diff is collapsed.
Click to expand it.
src/main.rs
+
44
−
3
View file @
6d861d98
...
@@ -3,9 +3,11 @@ use crate::delete::Delete;
...
@@ -3,9 +3,11 @@ use crate::delete::Delete;
use
crate
::
prune
::
Prune
;
use
crate
::
prune
::
Prune
;
use
clap
::{
Args
,
Parser
,
Subcommand
};
use
clap
::{
Args
,
Parser
,
Subcommand
};
use
colored
::
Colorize
;
use
colored
::
Colorize
;
use
configt
::
PartialPrune
;
mod
checkout
;
mod
checkout
;
mod
commit
;
mod
commit
;
mod
compact
;
mod
compact
;
mod
configt
;
mod
create_hooks
;
mod
create_hooks
;
mod
delete
;
mod
delete
;
mod
diff
;
mod
diff
;
...
@@ -58,7 +60,7 @@ enum Commands {
...
@@ -58,7 +60,7 @@ enum Commands {
DeleteHooks
,
DeleteHooks
,
/// Show differences between two commits of the `results` folder
/// Show differences between two commits of the `results` folder
Diff
(
Diff
),
Diff
(
Diff
),
/// Mount an old file/directory from one or multiple archive named afer
t
/// Mount an old file/directory from one or multiple archive named af
t
er
/// git commits into the .mount folder inside de project directory.
/// git commits into the .mount folder inside de project directory.
Mount
(
Mount
),
Mount
(
Mount
),
/// Unmount everything in the folder .mount
/// Unmount everything in the folder .mount
...
@@ -68,7 +70,7 @@ enum Commands {
...
@@ -68,7 +70,7 @@ enum Commands {
/// This is basically a wrapper of the borg delete command
/// This is basically a wrapper of the borg delete command
///
///
/// You can visit:
/// You can visit:
/// https://borgbackup.readthedocs.io/en/stable/usage/
delet
e.html for more details
///
<
https://borgbackup.readthedocs.io/en/stable/usage/
prun
e.html
>
for more details
///
///
/// This function don't free disk space until gblk compact is used
/// This function don't free disk space until gblk compact is used
Delete
(
Delete
),
Delete
(
Delete
),
...
@@ -78,7 +80,7 @@ enum Commands {
...
@@ -78,7 +80,7 @@ enum Commands {
/// This is basically a wrapper of the borg prune command
/// This is basically a wrapper of the borg prune command
///
///
/// You can visit:
/// You can visit:
/// https://borgbackup.readthedocs.io/en/stable/usage/prune.html for more details
///
<
https://borgbackup.readthedocs.io/en/stable/usage/prune.html
>
for more details
///
///
/// This function don't free disk space until gblk compact is used
/// This function don't free disk space until gblk compact is used
Prune
(
Prune
),
Prune
(
Prune
),
...
@@ -87,6 +89,12 @@ enum Commands {
...
@@ -87,6 +89,12 @@ enum Commands {
/// It is especially useful after deleting archives because compaction will
/// It is especially useful after deleting archives because compaction will
/// free repository space
/// free repository space
Compact
(
Compact
),
Compact
(
Compact
),
/// This command can bed used to add gblk configuration
///
/// It's useful when you want to defined to always keep archive in given
/// time interval without typing always the same prune command
#[clap(subcommand)]
Config
(
Config
),
}
}
#[derive(Debug,
Args)]
#[derive(Debug,
Args)]
...
@@ -206,6 +214,33 @@ struct Mount {
...
@@ -206,6 +214,33 @@ struct Mount {
last
:
Option
<
u8
>
,
last
:
Option
<
u8
>
,
}
}
#[derive(Debug,
Subcommand)]
enum
Config
{
/// Add a new parameter in the gblk config file to be able to automatically
/// prune some commits
Add
(
Add
),
/// Display the current gblk configuration
Show
,
/// Remove the configuration of a given key in prune
Rm
(
Rm
),
/// Prune using the project configuration
Prune
(
PartialPrune
),
}
#[derive(Debug,
Args)]
struct
Add
{
/// The name of the argument to add, see optional arguments of the prune subcommands
key
:
String
,
/// The value of the argument to add in the configuration file
value
:
String
,
}
#[derive(Debug,
Args)]
struct
Rm
{
/// The name of the argument to remove, see optional arguments of the prune subcommands
key
:
String
,
}
fn
main
()
{
fn
main
()
{
let
args
=
Cli
::
parse
();
let
args
=
Cli
::
parse
();
...
@@ -273,5 +308,11 @@ fn main() {
...
@@ -273,5 +308,11 @@ fn main() {
Commands
::
Compact
(
my_compact
)
=>
{
Commands
::
Compact
(
my_compact
)
=>
{
compact
::
launch_compact
(
my_compact
);
compact
::
launch_compact
(
my_compact
);
}
}
Commands
::
Config
(
conf
)
=>
match
conf
{
Config
::
Add
(
e
)
=>
configt
::
update_config
(
&
e
.key
,
&
e
.value
),
Config
::
Show
=>
configt
::
show
(),
Config
::
Rm
(
e
)
=>
configt
::
remove_config
(
&
e
.key
),
Config
::
Prune
(
pp
)
=>
configt
::
launch_config_prune
(
pp
),
},
}
}
}
}
This diff is collapsed.
Click to expand it.
src/prune.rs
+
25
−
0
View file @
6d861d98
use
crate
::
commit
;
use
crate
::
commit
;
use
crate
::
configt
::{
GblkConfig
,
PartialPrune
};
use
clap
::
Args
;
use
clap
::
Args
;
use
std
::{
use
std
::{
collections
::
HashMap
as
HM
,
collections
::
HashMap
as
HM
,
...
@@ -148,6 +149,30 @@ pub(crate) struct Prune {
...
@@ -148,6 +149,30 @@ pub(crate) struct Prune {
pub
(
crate
)
glob_archives
:
Option
<
String
>
,
pub
(
crate
)
glob_archives
:
Option
<
String
>
,
}
}
pub
(
crate
)
fn
new_prune
(
gblk_config
:
GblkConfig
,
partial_prune
:
PartialPrune
)
->
Prune
{
let
ss
=
match
gblk_config
.save_space
{
None
=>
false
,
Some
(
bool
)
=>
bool
,
};
Prune
{
dry_run
:
partial_prune
.dry_run
,
list
:
partial_prune
.list
,
stats
:
partial_prune
.stats
,
force
:
partial_prune
.force
,
save_space
:
ss
,
keep_within
:
gblk_config
.keep_within
,
keep_last
:
gblk_config
.keep_last
,
keep_minutely
:
gblk_config
.keep_minutely
,
keep_hourly
:
gblk_config
.keep_hourly
,
keep_daily
:
gblk_config
.keep_daily
,
keep_weekly
:
gblk_config
.keep_weekly
,
keep_monthly
:
gblk_config
.keep_monthly
,
keep_yearly
:
gblk_config
.keep_yearly
,
prefix
:
gblk_config
.prefix
,
glob_archives
:
gblk_config
.glob_archives
,
}
}
/// Function that add flags arguments in the delete commands
/// Function that add flags arguments in the delete commands
/// # Arguments
/// # Arguments
/// * `sd`: Struct containing all the data that can be used to build the delete command
/// * `sd`: Struct containing all the data that can be used to build the delete command
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment