Skip to content
This repository has been archived by the owner on Jul 25, 2022. It is now read-only.

Commit

Permalink
Implement new automatic snapshot feature
Browse files Browse the repository at this point in the history
Signed-off-by: Igor Pashev <[email protected]>
  • Loading branch information
ip1981 committed Nov 26, 2020
1 parent c948ece commit 93fa574
Show file tree
Hide file tree
Showing 21 changed files with 1,850 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 110 additions & 2 deletions iml-api/src/graphql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use iml_wire_types::{
graphql::{ServerProfile, ServerProfileInput},
graphql_duration::GraphQLDuration,
logs::{LogResponse, Meta},
snapshot::{ReserveUnit, Snapshot, SnapshotInterval, SnapshotRetention},
snapshot::{ReserveUnit, Snapshot, SnapshotInterval, SnapshotPolicy, SnapshotRetention},
task::Task,
Command, EndpointName, FsType, Job, LogMessage, LogSeverity, MessageClass, SortDir,
};
Expand Down Expand Up @@ -621,6 +621,27 @@ impl QueryRoot {

Ok(mount_command)
}

/// List all automatic snapshot policies.
async fn snapshot_policies(context: &Context) -> juniper::FieldResult<Vec<SnapshotPolicy>> {
let xs = sqlx::query!(r#"SELECT * FROM snapshot_policy"#)
.fetch(&context.pg_pool)
.map_ok(|x| SnapshotPolicy {
id: x.id,
filesystem: x.filesystem,
interval: x.interval.into(),
barrier: x.barrier,
keep: x.keep,
daily: x.daily,
weekly: x.weekly,
monthly: x.monthly,
last_run: x.last_run,
})
.try_collect()
.await?;

Ok(xs)
}
}

struct SnapshotIntervalName {
Expand Down Expand Up @@ -930,7 +951,7 @@ impl MutationRoot {
),
reserve_unit(description = "The unit of measurement associated with the reserve_value"),
keep_num(
description = "The minimum number of snapshots to keep. This is to avoid deleting all snapshots while pursuiting the reserve goal"
description = "The minimum number of snapshots to keep. This is to avoid deleting all snapshots while pursuing the reserve goal"
)
))]
/// Creates a new snapshot retention policy for the given `fsname`.
Expand Down Expand Up @@ -1085,6 +1106,67 @@ impl MutationRoot {
Ok(true)
}

#[graphql(arguments(
filesystem(description = "The filesystem to create snapshots with"),
interval(description = "How often a snapshot should be taken"),
use_barrier(
description = "Set write barrier before creating snapshot. The default value is `false`"
),
keep(description = "Number of the most recent snapshots to keep"),
daily(description = "Then, number of days when keep the most recent snapshot of each day"),
weekly(
description = "Then, number of weeks when keep the most recent snapshot of each week"
),
monthly(
description = "Then, number of months when keep the most recent snapshot of each month"
),
))]
/// Creates a new automatic snapshot policy.
async fn create_snapshot_policy(
context: &Context,
filesystem: String,
interval: GraphQLDuration,
barrier: Option<bool>,
keep: i32,
daily: Option<i32>,
weekly: Option<i32>,
monthly: Option<i32>,
) -> juniper::FieldResult<bool> {
sqlx::query!(
r#"
INSERT INTO snapshot_policy (
filesystem,
interval,
barrier,
keep,
daily,
weekly,
monthly
)
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (filesystem)
DO UPDATE SET
interval = EXCLUDED.interval,
barrier = EXCLUDED.barrier,
keep = EXCLUDED.keep,
daily = EXCLUDED.daily,
weekly = EXCLUDED.weekly,
monthly = EXCLUDED.monthly
"#,
filesystem,
PgInterval::try_from(interval.0)?,
barrier.unwrap_or(false),
keep,
daily.unwrap_or(0),
weekly.unwrap_or(0),
monthly.unwrap_or(0)
)
.fetch_optional(&context.pg_pool)
.await?;

Ok(true)
}

#[graphql(arguments(profile_name(description = "Name of the profile to remove")))]
async fn remove_server_profile(
context: &Context,
Expand Down Expand Up @@ -1116,6 +1198,32 @@ impl MutationRoot {
transaction.commit().await?;
Ok(true)
}

#[graphql(arguments(
filesystem(description = "The filesystem to remove snapshot policies for"),
id(description = "Id of the policy to remove"),
))]
/// Removes the automatic snapshot policy.
async fn remove_snapshot_policy(
context: &Context,
filesystem: Option<String>,
id: Option<i32>,
) -> juniper::FieldResult<bool> {
sqlx::query!(
r#"
DELETE FROM snapshot_policy
WHERE (filesystem IS NOT DISTINCT FROM $1)
OR (id IS NOT DISTINCT FROM $2)
"#,
filesystem,
id
)
.fetch_optional(&context.pg_pool)
.await?;

Ok(true)
}
}

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
Expand Down
102 changes: 102 additions & 0 deletions iml-graphql-queries/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,105 @@ pub mod list_retentions {
pub snapshot_retention_policies: Vec<SnapshotRetention>,
}
}

pub mod policy {
pub mod list {
use crate::Query;
use iml_wire_types::snapshot::SnapshotPolicy;

pub static QUERY: &str = r#"
query SnapshotPolicies {
snapshotPolicies {
id
filesystem
interval
barrier
keep
daily
weekly
monthly
last_run: lastRun
}
}
"#;

pub fn build() -> Query<()> {
Query {
query: QUERY.to_string(),
variables: None,
}
}

#[derive(Debug, Clone, serde::Deserialize)]
pub struct Resp {
#[serde(rename(deserialize = "snapshotPolicies"))]
pub snapshot_policies: Vec<SnapshotPolicy>,
}
}

pub mod create {
use crate::Query;

pub static QUERY: &str = r#"
mutation CreateSnapshotPolicy($filesystem: String!, $interval: Duration!, $barrier: Boolean,
$keep: Int!, $daily: Int, $weekly: Int, $monthly: Int) {
createSnapshotPolicy(filesystem: $filesystem, interval: $interval, barrier: $barrier,
keep: $keep, daily: $daily, weekly: $weekly, monthly: $monthly)
}
"#;

#[derive(Debug, serde::Serialize, Default, Clone)]
pub struct Vars {
pub filesystem: String,
pub interval: String,
pub barrier: Option<bool>,
pub keep: i32,
pub daily: Option<i32>,
pub weekly: Option<i32>,
pub monthly: Option<i32>,
}

pub fn build(vars: Vars) -> Query<Vars> {
Query {
query: QUERY.to_string(),
variables: Some(vars),
}
}

#[derive(Debug, Clone, serde::Deserialize)]
pub struct Resp {
#[serde(rename(deserialize = "createSnapshotPolicy"))]
pub snapshot_policy: bool,
}
}

pub mod remove {
use crate::Query;

pub static QUERY: &str = r#"
mutation RemoveSnapshotPolicy($filesystem: String!) {
removeSnapshotPolicy(filesystem: $filesystem)
}
"#;

#[derive(Debug, serde::Serialize, Default)]
pub struct Vars {
filesystem: String,
}

pub fn build(filesystem: impl ToString) -> Query<Vars> {
Query {
query: QUERY.to_string(),
variables: Some(Vars {
filesystem: filesystem.to_string(),
}),
}
}

#[derive(Debug, Clone, serde::Deserialize)]
pub struct Resp {
#[serde(rename(deserialize = "removeSnapshotPolicy"))]
pub snapshot_policy: bool,
}
}
}
3 changes: 3 additions & 0 deletions iml-gui/crate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,9 @@ fn handle_record_change(
ArcRecord::SnapshotRetention(x) => {
model.records.snapshot_retention.insert(x.id, Arc::clone(&x));
}
ArcRecord::SnapshotPolicy(x) => {
model.records.snapshot_policy.insert(x.id, Arc::clone(&x));
}
ArcRecord::StratagemConfig(x) => {
model.records.stratagem_config.insert(x.id, Arc::clone(&x));

Expand Down
Loading

0 comments on commit 93fa574

Please sign in to comment.