Script to forget old snaphots relative to current time (written in R)

The restic forget command operates relative to the newest snapshot in each group. In some cases, it is important do remove snapshots relative to the current time instead. It is formatted as a reprex, with example output included as comments.

The script can also be modified to implement forgetting according to other custom rules that may not be supported by the built-in command.

WARNING: This script can result in the forgetting of all backups in a group and should be used with care. In most cases the built-in restic forget functionality is preferrable. Unmodified, the script forgets all snapshots older than 1 month and 16 days, and with --dry-run enabled.

# Packages
library(tidyverse)
library(jsonlite,  warn.conflicts = FALSE)
library(lubridate, warn.conflicts = FALSE)

# Configuration
restic_repo <- "./repo"
restic_pass <- "x"
max_age     <- dmonths(1)+ddays(16)
dry_run     <- TRUE

# Generate list of snapshots
Sys.setenv(RESTIC_REPOSITORY=restic_repo)
Sys.setenv(RESTIC_PASSWORD=restic_pass)
snapshots_json <- system("restic snapshots --json", intern=TRUE)

# Prepare the data as a tibble with an age column
d.snapshots <- fromJSON(snapshots_json) %>% 
  as_tibble() %>% 
  mutate(time=as_datetime(time)) %>%
  arrange(time) %>%
  select(time, short_id, id) %>%
  mutate(age=as.difftime(now()-time,format="%d"))
d.snapshots
#> # A tibble: 38 x 4
#>    time                short_id id                                     age      
#>    <dttm>              <chr>    <chr>                                  <drtn>   
#>  1 2021-05-02 22:12:15 17039268 170392686423ae50d2de81f1685eb417651ab… 59.50696…
#>  2 2021-05-02 22:13:24 b7529606 b75296060204f6cf4a5e341622cfb67d6a972… 59.50617…
#>  3 2021-05-02 22:13:49 a5d5cdc6 a5d5cdc60f6f4c03f09bb63e0675f844b40ab… 59.50587…
#>  4 2021-05-02 22:14:09 34b7cd77 34b7cd77964081319cf54deabe8f4cb35f3f4… 59.50564…
#>  5 2021-05-02 22:14:23 10341261 10341261a0149149a89177495357574c9e705… 59.50548…
#>  6 2021-05-16 10:26:21 f97b5328 f97b5328079d79e25267e5bc86cfade1648f6… 45.99717…
#>  7 2021-05-16 10:28:00 551894ed 551894ed3bc15066065ff019b6d7a79f0f135… 45.99602…
#>  8 2021-05-16 10:34:49 e5f0fa2b e5f0fa2be41935056aa00e8d7116a1b5c4b88… 45.99129…
#>  9 2021-05-16 10:36:29 caf12731 caf127316b5a6a0f86c52a82526ed20681fed… 45.99014…
#> 10 2021-05-16 10:37:30 b2ba5c7c b2ba5c7ce15c4935b55692cce1bbc4607f84f… 45.98942…
#> # … with 28 more rows

# Filter snapshots older than a particular date, return in a single string
snapshots_to_forget <- d.snapshots %>%
  filter(age>max_age) %>%
  pull(id) %>%
  paste(collapse=" ")
snapshots_to_forget
#> [1] "170392686423ae50d2de81f1685eb417651ab2ebf7fd238222f3a16fb3855d33 b75296060204f6cf4a5e341622cfb67d6a9726c4e2daaf645b0f3fc0242d513f a5d5cdc60f6f4c03f09bb63e0675f844b40ab87eea7a635db4404e22577b93bb 34b7cd77964081319cf54deabe8f4cb35f3f41d47aff9202aea93660d3e1f82d 10341261a0149149a89177495357574c9e705e657e88b360b41361b69c37c319"

# run the forget
dry_run_param <- if_else(dry_run,"--dry-run","")
system(paste("restic forget", dry_run_param, snapshots_to_forget), intern=TRUE) %>% cat(sep="\n")
#> Would have removed the following snapshots:
#> {10341261 17039268 34b7cd77 a5d5cdc6 b7529606}

Created on 2021-07-01 by the reprex package (v2.0.0)

1 Like