zfs_mgmt 0.2.5 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +12 -0
- data/lib/zfs_mgmt.rb +56 -14
- data/lib/zfs_mgmt/version.rb +1 -1
- data/zfs_mgmt.gemspec +3 -3
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0e8d3af1ac03924544fff40f3978ba979b8b4b2adfa968971de7f9c571e503d
|
4
|
+
data.tar.gz: e555e236db39683a9b8fd3c7d12bcb5b9c7800aee285898670acef966f7bd321
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b6f60006226fe6664c3d9ec3364900354d4fbca988615956f6df27f8d76901428845ed122180cb647dd7c391ca6a518516e1734875f6968e57c0c78f2e0ad60
|
7
|
+
data.tar.gz: fa4cd0c9018def638b438fc27ddf855651e61c62d739c5f0c34eb880098bc3558e895826b7de0392d0c10f342d938fc20b524bea67fbcc2ce84b20411b6d4189
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -165,6 +165,18 @@ to match the specified policy for the zfs, nor will they be deleted.
|
|
165
165
|
The intended use is match zfs send/recv snapshots or hand-created
|
166
166
|
snapshots, etc. ie: ^syncoid_
|
167
167
|
|
168
|
+
### zfsmgmt:prefersnaps
|
169
|
+
Prefer snapshots matching this regexp pattern. The oldest/youngest
|
170
|
+
snapshot matching this pattern will be used depending on strategy, but
|
171
|
+
if no snapshots are found matching this pattern use any snapshot as
|
172
|
+
constrained by the matchsnaps and ignoresnaps options (if set.)
|
173
|
+
|
174
|
+
### zfsmgmt:strategy (default: oldest)
|
175
|
+
Save the oldest snapshot fitting a given time frame as specificed by
|
176
|
+
the policy, unless this value is set to "youngest" in which case use
|
177
|
+
the most recent snapshot for any given time frame. The default is
|
178
|
+
oldest and unless the property is set to youngest oldest will be used.
|
179
|
+
|
168
180
|
### zfsmgmt:snapshot
|
169
181
|
If this property is 'true' then create a snapshot in the format of
|
170
182
|
zfsmgmt-%FT%T%z. If this property is 'recursive' then create a
|
data/lib/zfs_mgmt.rb
CHANGED
@@ -44,6 +44,7 @@ module ZfsMgmt
|
|
44
44
|
'minage',
|
45
45
|
'matchsnaps',
|
46
46
|
'ignoresnaps',
|
47
|
+
'prefersnaps',
|
47
48
|
'snapshot',
|
48
49
|
'snap_prefix',
|
49
50
|
'snap_timestamp',
|
@@ -117,13 +118,11 @@ module ZfsMgmt
|
|
117
118
|
if props.has_key?('zfsmgmt:minage')
|
118
119
|
minage = timespec_to_seconds(props['zfsmgmt:minage'])
|
119
120
|
end
|
120
|
-
strategy = '
|
121
|
-
if props.has_key?('zfsmgmt:strategy') and props['zfsmgmt:strategy'] == '
|
122
|
-
strategy = '
|
121
|
+
strategy = 'oldest'
|
122
|
+
if props.has_key?('zfsmgmt:strategy') and props['zfsmgmt:strategy'] == 'youngest'
|
123
|
+
strategy = 'youngest'
|
123
124
|
end
|
124
125
|
sorted = snaps.keys.sort { |a,b| snaps[b]['creation'] <=> snaps[a]['creation'] }
|
125
|
-
# never consider the latest snapshot for anything
|
126
|
-
newest_snapshot_name = sorted.shift
|
127
126
|
|
128
127
|
counters = policy_parser(props['zfsmgmt:policy'])
|
129
128
|
$logger.debug(counters)
|
@@ -147,12 +146,16 @@ module ZfsMgmt
|
|
147
146
|
$date_patterns.each do |d,p|
|
148
147
|
pat = snaptime.strftime(p)
|
149
148
|
if saved[d].has_key?(pat)
|
150
|
-
|
149
|
+
#pp props['zfsmgmt:prefersnaps'],snap_name.split('@')[1], saved[d][pat].split('@')[1]
|
150
|
+
if props.has_key?('zfsmgmt:prefersnaps') and /#{props['zfsmgmt:prefersnaps']}/ !~ saved[d][pat].split('@')[1] and /#{props['zfsmgmt:prefersnaps']}/ =~ snap_name.split('@')[1]
|
151
|
+
$logger.debug("updating the saved snapshot, we prefer this one: \"#{pat}\" to #{snap_name} at #{snaptime}")
|
152
|
+
saved[d][pat] = snap_name
|
153
|
+
elsif strategy == 'oldest' and ( not props.has_key?('zfsmgmt:prefersnaps') or /#{props['zfsmgmt:prefersnaps']}/ =~ snap_name.split('@')[1] )
|
151
154
|
# update the existing current save snapshot for this timeframe
|
152
155
|
$logger.debug("updating the saved snapshot for \"#{pat}\" to #{snap_name} at #{snaptime}")
|
153
156
|
saved[d][pat] = snap_name
|
154
157
|
else
|
155
|
-
$logger.debug("not updating the saved snapshot for \"#{pat}\" to #{snap_name} at #{snaptime}, we have
|
158
|
+
$logger.debug("not updating the saved snapshot for \"#{pat}\" to #{snap_name} at #{snaptime}, we have a younger snap")
|
156
159
|
end
|
157
160
|
elsif counters[d] > 0
|
158
161
|
# new pattern, and we want to save more snaps of this type
|
@@ -173,12 +176,15 @@ module ZfsMgmt
|
|
173
176
|
# delete everything not in the list of saved snapshots
|
174
177
|
deleteme = sorted - saved_snaps
|
175
178
|
deleteme = deleteme.select { |snap|
|
176
|
-
if props.has_key?('zfsmgmt:ignoresnaps') and /#{props['zfsmgmt:ignoresnaps']}/ =~ snap
|
179
|
+
if props.has_key?('zfsmgmt:ignoresnaps') and /#{props['zfsmgmt:ignoresnaps']}/ =~ snap.split('@')[1]
|
177
180
|
$logger.debug("skipping #{snap} because it matches ignoresnaps pattern: #{props['zfsmgmt:ignoresnaps']}")
|
178
181
|
false
|
179
182
|
elsif minage > 0 and Time.at(snaps[snap]['creation'] + minage) > Time.now()
|
180
183
|
$logger.debug("skipping due to minage: #{snap} #{local_epoch_to_datetime(snaps[snap]['creation']).strftime('%F %T')}")
|
181
184
|
false
|
185
|
+
elsif snap == sorted[0] # the very newest snap
|
186
|
+
$logger.debug("skipping due to newest: #{snap} #{local_epoch_to_datetime(snaps[snap]['creation']).strftime('%F %T')}")
|
187
|
+
false
|
182
188
|
else
|
183
189
|
true
|
184
190
|
end
|
@@ -224,10 +230,10 @@ module ZfsMgmt
|
|
224
230
|
end
|
225
231
|
# print a table of saved snapshots with the reasons it is being saved
|
226
232
|
table = Text::Table.new
|
227
|
-
table.head = [
|
233
|
+
table.head = [zfs,'creation','hourly','daily','weekly','monthly','yearly']
|
228
234
|
table.rows = []
|
229
235
|
saved_snaps.sort { |a,b| snaps[b]['creation'] <=> snaps[a]['creation'] }.each do |snap|
|
230
|
-
table.rows << [snap,local_epoch_to_datetime(snaps[snap]['creation'])] + find_saved_reason(saved,snap)
|
236
|
+
table.rows << [snap.split('@')[1],local_epoch_to_datetime(snaps[snap]['creation'])] + find_saved_reason(saved,snap)
|
231
237
|
end
|
232
238
|
print table.to_s
|
233
239
|
end
|
@@ -244,17 +250,50 @@ module ZfsMgmt
|
|
244
250
|
(saved,saved_snaps,deleteme) = snapshot_destroy_policy(zfs,props,snaps)
|
245
251
|
|
246
252
|
$logger.info("deleting #{deleteme.length} snapshots for #{zfs}")
|
253
|
+
deleteme.reverse! # oldest first for removal
|
254
|
+
|
255
|
+
# holdme = deleteme
|
256
|
+
# holds = []
|
257
|
+
# while holdme.length > 0
|
258
|
+
# for i in 0..(holdme.length - 1) do
|
259
|
+
# max = holdme.length - 1 - i
|
260
|
+
# bigarg = holdme[0..max].join(" ") # snaps joined by
|
261
|
+
# com = "zfs holds -H #{bigarg}"
|
262
|
+
# $logger.debug("size of bigarg: #{bigarg.length} size of com: #{com.length}")
|
263
|
+
# if bigarg.length >= 131072 or com.length >= (2097152-10000)
|
264
|
+
# next
|
265
|
+
# end
|
266
|
+
# $logger.info(com)
|
267
|
+
# so,se,status = Open3.capture3(com)
|
268
|
+
# if status.signaled?
|
269
|
+
# $logger.error("process was signalled \"#{com}\", termsig #{status.termsig}")
|
270
|
+
# raise 'ZfsHoldsError'
|
271
|
+
# end
|
272
|
+
# unless status.success?
|
273
|
+
# $logger.error("failed to execute \"#{com}\", exit status #{status.exitstatus}")
|
274
|
+
# so.split("\n").each { |l| $logger.debug("stdout: #{l}") }
|
275
|
+
# se.split("\n").each { |l| $logger.error("stderr: #{l}") }
|
276
|
+
# raise 'ZfsHoldsError'
|
277
|
+
# end
|
278
|
+
# so.split("\n").each do |line|
|
279
|
+
# holds.append(line.split("\t")[0])
|
280
|
+
# end
|
281
|
+
# holdme = holdme - holdme[0..max]
|
282
|
+
# break
|
283
|
+
# end
|
284
|
+
# end
|
285
|
+
# $logger.debug("found #{holds.length} snapshots with holds: #{holds.join(',')}")
|
286
|
+
# deleteme = deleteme - holds
|
247
287
|
com_base = "zfs destroy -p"
|
288
|
+
if deleteme.length > 0
|
289
|
+
com_base = "#{com_base}d"
|
290
|
+
end
|
248
291
|
if noop
|
249
292
|
com_base = "#{com_base}n"
|
250
293
|
end
|
251
294
|
if verbopt
|
252
295
|
com_base = "#{com_base}v"
|
253
296
|
end
|
254
|
-
deleteme.reverse! # oldest first for removal
|
255
|
-
deleteme.each do |snap_name|
|
256
|
-
$logger.debug("delete: #{snap_name} #{local_epoch_to_datetime(snaps[snap_name]['creation']).strftime('%F %T')}")
|
257
|
-
end
|
258
297
|
while deleteme.length > 0
|
259
298
|
for i in 0..(deleteme.length - 1) do
|
260
299
|
max = deleteme.length - 1 - i
|
@@ -268,6 +307,9 @@ module ZfsMgmt
|
|
268
307
|
$logger.info(com)
|
269
308
|
deleteme = deleteme - deleteme[0..max]
|
270
309
|
system(com)
|
310
|
+
if $?.exitstatus != 0
|
311
|
+
$logger.error("zfs exited with non-zero status: #{$?.exitstatus}")
|
312
|
+
end
|
271
313
|
break
|
272
314
|
end
|
273
315
|
end
|
data/lib/zfs_mgmt/version.rb
CHANGED
data/zfs_mgmt.gemspec
CHANGED
@@ -39,8 +39,8 @@ Gem::Specification.new do |spec|
|
|
39
39
|
spec.add_development_dependency "bundler", "~> 1.16"
|
40
40
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
41
41
|
spec.add_development_dependency "rspec", "~> 3.0"
|
42
|
-
spec.add_development_dependency "thor", "~> 1.0
|
43
|
-
spec.add_development_dependency "text-table", "~> 1.2
|
44
|
-
spec.add_development_dependency "filesize", "~> 0.2
|
42
|
+
spec.add_development_dependency "thor", "~> 1.0"
|
43
|
+
spec.add_development_dependency "text-table", "~> 1.2"
|
44
|
+
spec.add_development_dependency "filesize", "~> 0.2"
|
45
45
|
|
46
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zfs_mgmt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aran Cox
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,42 +58,42 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0
|
61
|
+
version: '1.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0
|
68
|
+
version: '1.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: text-table
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.2
|
75
|
+
version: '1.2'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1.2
|
82
|
+
version: '1.2'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: filesize
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.2
|
89
|
+
version: '0.2'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.2
|
96
|
+
version: '0.2'
|
97
97
|
description:
|
98
98
|
email:
|
99
99
|
- arancox@gmail.com
|
@@ -149,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
149
|
- !ruby/object:Gem::Version
|
150
150
|
version: '0'
|
151
151
|
requirements: []
|
152
|
-
rubygems_version: 3.
|
152
|
+
rubygems_version: 3.1.2
|
153
153
|
signing_key:
|
154
154
|
specification_version: 4
|
155
155
|
summary: Misc. helpers regarding snapshots and send/recv.
|