Subversion Repositories zfs_utils

Rev

Rev 55 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 55 Rev 60
Line 1... Line 1...
1
## cleanSnaps
1
## cleanSnaps
2
 
2
 
3
Clean old ZFS snapshots whose names include a TTL suffix. This document describes usage, accepted snapshot name patterns, options, examples and notes.
3
Clean old ZFS snapshots whose names include a TTL suffix. This document describes usage, accepted snapshot name patterns, options, examples and notes.
4
 
4
 
-
 
5
**Version:** 1.1  
-
 
6
**Author:** R. W. Rodlico  
-
 
7
**License:** Simplified BSD License (FreeBSD License)
-
 
8
 
5
### Purpose
9
### Purpose
6
 
10
 
7
`cleanSnaps` is a small Perl utility that scans a list of ZFS snapshots and removes or reports snapshots that have exceeded their configured TTL. TTLs are encoded in snapshot names as a numeric suffix plus a unit (s, m, h, d, w, y). The script supports date/time-stamped snapshot names and an optional time-shift for testing.
11
`cleanSnaps` is a small Perl utility that scans a list of ZFS snapshots and removes or reports snapshots that have exceeded their configured TTL. TTLs are encoded in snapshot names as a numeric suffix plus a unit (s, m, h, d, w, y). The script supports date/time-stamped snapshot names and an optional time-shift for testing.
8
 
12
 
9
### Location
13
### Location
Line 11... Line 15...
11
Script: `cleanSnaps` (same directory as this file)
15
Script: `cleanSnaps` (same directory as this file)
12
 
16
 
13
### Synopsis
17
### Synopsis
14
 
18
 
15
```
19
```
16
cleanSnaps [--force|-f] [--verbose|-v] [--timeshift|-t <shift>] [--help|-h] [pool]
20
cleanSnaps [--force|-f] [--verbose|-v] [--timeshift|-t <shift>] [--unmatched|-u] [--version|-V] [--help|-h] [pool]
17
```
21
```
18
 
22
 
19
- `--timeshift, -t <shift>` — Apply an artificial time-shift. The script accepts a signed or unsigned quantity with a unit (examples: `30d`, `-4w`, `+3d`, `3600s`). Units: s, m, h, d, w, y. Useful for testing TTL expiry without changing the system clock. A positive shift moves “now” forward (so more snapshots appear expired); a negative shift moves “now” backward. No sign assumed to be backwards.
-
 
20
- `--force, -f` — Actually destroy snapshots. By default the script runs in safe (non-destructive) mode and only reports candidate snapshots.
23
- `--force, -f` — Actually destroy snapshots. By default the script runs in safe (non-destructive) mode and only reports candidate snapshots.
21
- `--verbose, -v` — Verbose logging; prints keep/skip messages and extra information.
24
- `--verbose, -v` — Verbose logging; prints keep/skip messages and extra information.
-
 
25
- `--timeshift, -t <shift>` — Apply an artificial time-shift. The script accepts a signed or unsigned quantity with a unit (examples: `30d`, `-4w`, `+3d`, `3600s`). Units: s, m, h, d, w, y. Useful for testing TTL expiry without changing the system clock. A positive shift moves "now" forward (so more snapshots appear expired); a negative shift moves "now" backward. No sign assumed to be backwards.
-
 
26
- `--unmatched, -u` — ONLY clean snapshots that don't match the retention pattern. When this flag is set, normal retention/TTL processing is skipped entirely. Only snapshots that fail to match the expected date/time + TTL pattern (or have unparseable dates) are marked for removal. This is useful for cleaning up snapshots with incorrect naming conventions.
-
 
27
- `--version, -V` — Show version information and exit.
22
- `--help, -h` — Show help/usage and exit.
28
- `--help, -h` — Show help/usage and exit.
23
- `pool` (optional) — Restrict processing to snapshots whose pool name matches this string.
29
- `pool` (optional) — Restrict processing to snapshots whose pool name matches this string.
24
 
30
 
25
When called without a positional `pool` argument, the script will process snapshots from standard input or from a `zfs list` invocation performed by the script. (See the script headers and tests for details.)
31
When called without a positional `pool` argument, the script will process snapshots from standard input or from a `zfs list` invocation performed by the script. (See the script headers and tests for details.)
26
 
32
 
Line 61... Line 67...
61
- Capture group 1: the date or date-time stamp. Accepts `YYYY-MM-DD` or `YYYY-MM-DD_HH:MM`/`YYYY-MM-DD_HH.MM.SS` styles. The separator between date and time can be `T`, space, or underscore; time separators may be `:` or `.`.
67
- Capture group 1: the date or date-time stamp. Accepts `YYYY-MM-DD` or `YYYY-MM-DD_HH:MM`/`YYYY-MM-DD_HH.MM.SS` styles. The separator between date and time can be `T`, space, or underscore; time separators may be `:` or `.`.
62
- Capture group 2: the numeric TTL quantity (one or more digits).
68
- Capture group 2: the numeric TTL quantity (one or more digits).
63
- Capture group 3: the TTL unit, one of `s m h d w y` (seconds, minutes, hours, days, weeks, years).
69
- Capture group 3: the TTL unit, one of `s m h d w y` (seconds, minutes, hours, days, weeks, years).
64
- The regex allows arbitrary text between the date/time stamp and the TTL token, and requires the TTL token to be at the end of the snapshot name.
70
- The regex allows arbitrary text between the date/time stamp and the TTL token, and requires the TTL token to be at the end of the snapshot name.
65
 
71
 
66
If a snapshot name does not match this pattern it will be ignored by `cleanSnaps`.
72
If a snapshot name does not match this pattern it will be ignored by `cleanSnaps` (unless the `--unmatched` flag is used).
67
 
73
 
68
### Behavior
74
### Behavior
69
 
75
 
-
 
76
**Normal mode (without --unmatched):**
70
- By default, the script calculates the expiry time as the date/time parsed from the snapshot name plus the TTL interval. If the resulting expiry timestamp is earlier than the current time (adjusted by any `--timeshift`), the snapshot is considered expired and will be listed. Use `--force` to perform destruction via `zfs destroy`.
77
- The script calculates the expiry time as the date/time parsed from the snapshot name plus the TTL interval. If the resulting expiry timestamp is earlier than the current time (adjusted by any `--timeshift`), the snapshot is considered expired and will be listed. 
-
 
78
- Snapshots that don't match the pattern are skipped and reported in verbose mode.
-
 
79
- Use `--force` to perform destruction via `zfs destroy`.
-
 
80
 
-
 
81
**Unmatched mode (with --unmatched):**
-
 
82
- The script ONLY processes snapshots that fail to match the expected pattern.
-
 
83
- Normal retention/TTL logic is completely skipped for snapshots that match the pattern.
-
 
84
- Only snapshots with names that don't match the date/time + TTL regex (or have unparseable dates) are marked for removal.
-
 
85
- This mode is useful for cleaning up incorrectly named snapshots while preserving all properly formatted ones.
-
 
86
 
-
 
87
**Both modes:**
71
- The script prints actions it would take; in its default (safe) mode it only reports candidate snapshots. Use `--verbose` for additional keep/skip messages and context.
88
- The script prints actions it would take; in its default (safe) mode it only reports candidate snapshots. Use `--verbose` for additional keep/skip messages and context.
72
 
89
 
73
### Examples
90
### Examples
74
 
91
 
75
- Run with a 30-day forward time-shift (simulate time 30 days later):
92
**Normal retention mode:**
76
 
93
 
-
 
94
- Run with a 30-day backward time-shift (simulate time 30 days earlier, ie will retain an additional 30 days of snapshots):
-
 
95
 
77
```
96
```bash
78
cleanSnaps -t 30d
97
cleanSnaps -t 30d # same as -30d
79
cleanSnaps -t 2592000   # equivalent (30 days in seconds)
98
cleanSnaps -t 2592000   # equivalent (30 days in seconds)
80
```
99
```
81
 
100
 
82
- Actually remove all snapshots found from pool tank, displaying each step while doing so:
101
- Actually remove all expired snapshots from pool tank, displaying each step:
83
 
102
 
84
```
103
```bash
85
cleanSnaps -f -v tank
104
cleanSnaps -f -v tank
86
```
105
```
87
 
106
 
88
- Restrict processing to pool `tank` (only snapshots whose pool prefix matches `tank` will be considered):
107
- Restrict processing to pool `tank` (only snapshots whose pool prefix matches `tank` will be considered):
89
 
108
 
90
```
109
```bash
91
cleanSnaps tank
110
cleanSnaps tank
92
```
111
```
93
 
112
 
-
 
113
**Unmatched snapshot cleanup:**
-
 
114
 
94
- Feed the script a list of snapshots on stdin (for testing):
115
- List all snapshots that don't match the expected naming pattern:
-
 
116
 
-
 
117
```bash
-
 
118
cleanSnaps -v -u
-
 
119
```
-
 
120
 
-
 
121
- Actually remove snapshots with incorrect names (useful for cleaning up after naming convention changes):
95
 
122
 
-
 
123
```bash
-
 
124
cleanSnaps -f -u tank
96
```
125
```
-
 
126
 
-
 
127
**Version and help:**
-
 
128
 
-
 
129
- Show version information:
-
 
130
 
-
 
131
```bash
-
 
132
cleanSnaps --version
-
 
133
cleanSnaps -V
-
 
134
```
-
 
135
 
-
 
136
- Show help:
-
 
137
 
-
 
138
```bash
97
cat sample-snapshots.txt | cleanSnaps -t 3600
139
cleanSnaps --help
-
 
140
cleanSnaps -h
98
```
141
```
99
 
142
 
100
### Safety & Notes
143
### Safety & Notes
101
 
144
 
102
- The script includes a help flag and a Simplified BSD license header. It is safe by default (it reports candidates without destroying them). Nevertheless, exercise caution when running on production systems — prefer testing with `--timeshift` or sample input first.
145
- The script includes a help flag and a Simplified BSD license header. It is safe by default (it reports candidates without destroying them). Nevertheless, exercise caution when running on production systems — prefer testing with `--timeshift` or sample input first.
103
- The script parses a variety of date/time formats but will ignore snapshot entries that do not match the expected patterns; those snapshots are left untouched.
146
- In normal mode, the script parses a variety of date/time formats but will ignore snapshot entries that do not match the expected patterns; those snapshots are left untouched.
-
 
147
- The `--unmatched` flag inverts this behavior: it ONLY targets snapshots that don't match the pattern, making it safe to use for cleaning up incorrectly named snapshots without affecting your properly formatted ones.
104
- The script depends on standard Perl modules available in most Perl 5 installations. See the script header for exact module imports.
148
- The script depends on standard Perl modules available in most Perl 5 installations. See the script header for exact module imports.
-
 
149
- Always run without `--force` first to review what would be deleted.
105
 
150
 
106
### Tests
151
### Tests
107
 
152
 
108
There is a test harness in the repository (see `cleanSnaps/test_cleanSnaps.pl`) which includes sample snapshot names covering date/time formats, dot/colon time separators, and the `h` (hour) TTL unit. Use that test to validate behavior before running against real ZFS pools.
153
There is a test harness in the repository (see `cleanSnaps/test_cleanSnaps.pl`) which includes sample snapshot names covering date/time formats, dot/colon time separators, and the `h` (hour) TTL unit. The test suite includes:
-
 
154
 
-
 
155
1. **TEST 1**: Validates normal retention logic - snapshots are correctly kept or removed based on TTL
-
 
156
2. **TEST 2**: Validates `--unmatched` flag - only unmatched snapshots are removed, matched snapshots are skipped
-
 
157
3. **TEST 3**: Validates `--version` flag - version information is displayed correctly
-
 
158
 
-
 
159
Run the test with: `perl test_cleanSnaps.pl`
-
 
160
 
-
 
161
Use the test to validate behavior before running against real ZFS pools.
-
 
162
 
-
 
163
You can also include a filename which contains a list of snapshots and all tests will be run against that.
109
 
164
 
110
### Contributing / Changes
165
### Contributing / Changes
111
 
166
 
112
If you update the script, update this documentation to reflect new options, changes in the snapshot matching regex, or different behaviors for dry-run vs. delete modes.
167
If you update the script, update this documentation to reflect new options, changes in the snapshot matching regex, or different behaviors for dry-run vs. delete modes.
113
 
168