zfs_mgmt 0.3.0 → 0.3.5
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/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +5 -1
- data/bin/zfsmgr +4 -0
- data/lib/zfs_mgmt.rb +42 -7
- data/lib/zfs_mgmt/restic.rb +33 -0
- data/lib/zfs_mgmt/version.rb +1 -1
- data/zfs_mgmt.gemspec +3 -3
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bce5f90411d08b54334f8694e7956f718c1e63995f2c799b95cb170b302c2c8a
|
4
|
+
data.tar.gz: 1d82a41657f40fe371814210be392d8c34be333816530fcff6a67ae778dc120b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e500b4cc3b155528c470c5aa26338a948e783a5f951a7a5e0d6c05b6739c07cccd6bfe0a1dd001a34722f47e611cc85e2f931d8e3cbca58e37b0f3b0d23606da
|
7
|
+
data.tar.gz: d3ca6969f760260449f85d99e05133f542700f9d0322a84f771cd157d3ec0729c2e86dc33f0326c53b1f35065cb28b879bbad85c6e422c4bae95b20cc9d21f06
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -180,7 +180,11 @@ oldest and unless the property is set to youngest oldest will be used.
|
|
180
180
|
### zfsmgmt:snapshot
|
181
181
|
If this property is 'true' then create a snapshot in the format of
|
182
182
|
zfsmgmt-%FT%T%z. If this property is 'recursive' then create a
|
183
|
-
recursive snapshot of this zfs
|
183
|
+
recursive snapshot of this zfs, but only on zfs where this property is
|
184
|
+
local. If this property is set to the string 'local' and the property
|
185
|
+
is set locally, it will create a snapshot. The intention is that you
|
186
|
+
would use 'local' when you want a zfs snapshot for the filesystem, but
|
187
|
+
NOT it's descendant filesystems.
|
184
188
|
|
185
189
|
### zfsmgmt:snap_prefix
|
186
190
|
Change the zfsmgmt portion of created snapshots, ie: 'autosnap' would
|
data/bin/zfsmgr
CHANGED
@@ -35,6 +35,10 @@ class ZfsMgr < Thor
|
|
35
35
|
end
|
36
36
|
desc "snapshot SUBCOMMAND ...ARGS", "manage snapshots"
|
37
37
|
subcommand "snapshot", Snapshot
|
38
|
+
desc "list SUBCOMMAND ...ARGS", "list filesystems"
|
39
|
+
subcommand "list", ZfsMgmtList
|
40
|
+
desc "restic SUBCOMMAND ...ARGS", "backup zfs to restic"
|
41
|
+
subcommand "restic", ZfsMgmtRestic
|
38
42
|
end
|
39
43
|
|
40
44
|
ZfsMgr.start(ARGV)
|
data/lib/zfs_mgmt.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
require "zfs_mgmt/version"
|
3
|
+
require "zfs_mgmt/restic"
|
3
4
|
require 'pp'
|
4
5
|
require 'date'
|
5
6
|
require 'logger'
|
@@ -230,10 +231,10 @@ module ZfsMgmt
|
|
230
231
|
end
|
231
232
|
# print a table of saved snapshots with the reasons it is being saved
|
232
233
|
table = Text::Table.new
|
233
|
-
table.head = [
|
234
|
+
table.head = [zfs,'creation','hourly','daily','weekly','monthly','yearly']
|
234
235
|
table.rows = []
|
235
236
|
saved_snaps.sort { |a,b| snaps[b]['creation'] <=> snaps[a]['creation'] }.each do |snap|
|
236
|
-
table.rows << [snap,local_epoch_to_datetime(snaps[snap]['creation'])] + find_saved_reason(saved,snap)
|
237
|
+
table.rows << [snap.split('@')[1],local_epoch_to_datetime(snaps[snap]['creation'])] + find_saved_reason(saved,snap)
|
237
238
|
end
|
238
239
|
print table.to_s
|
239
240
|
end
|
@@ -250,6 +251,11 @@ module ZfsMgmt
|
|
250
251
|
(saved,saved_snaps,deleteme) = snapshot_destroy_policy(zfs,props,snaps)
|
251
252
|
|
252
253
|
$logger.info("deleting #{deleteme.length} snapshots for #{zfs}")
|
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
|
+
|
253
259
|
com_base = "zfs destroy -p"
|
254
260
|
if deleteme.length > 0
|
255
261
|
com_base = "#{com_base}d"
|
@@ -260,10 +266,6 @@ module ZfsMgmt
|
|
260
266
|
if verbopt
|
261
267
|
com_base = "#{com_base}v"
|
262
268
|
end
|
263
|
-
deleteme.reverse! # oldest first for removal
|
264
|
-
deleteme.each do |snap_name|
|
265
|
-
$logger.debug("delete: #{snap_name} #{local_epoch_to_datetime(snaps[snap_name]['creation']).strftime('%F %T')}")
|
266
|
-
end
|
267
269
|
while deleteme.length > 0
|
268
270
|
for i in 0..(deleteme.length - 1) do
|
269
271
|
max = deleteme.length - 1 - i
|
@@ -277,6 +279,9 @@ module ZfsMgmt
|
|
277
279
|
$logger.info(com)
|
278
280
|
deleteme = deleteme - deleteme[0..max]
|
279
281
|
system(com)
|
282
|
+
if $?.exitstatus != 0
|
283
|
+
$logger.error("zfs exited with non-zero status: #{$?.exitstatus}")
|
284
|
+
end
|
280
285
|
break
|
281
286
|
end
|
282
287
|
end
|
@@ -306,8 +311,15 @@ module ZfsMgmt
|
|
306
311
|
end
|
307
312
|
dt = DateTime.now
|
308
313
|
zfsget(properties: custom_properties()).each do |zfs,props|
|
314
|
+
unless /#{filter}/ =~ zfs
|
315
|
+
next
|
316
|
+
end
|
309
317
|
# zfs must have snapshot set to true or recursive
|
310
|
-
if props.has_key?('zfsmgmt:snapshot') and
|
318
|
+
if props.has_key?('zfsmgmt:snapshot') and
|
319
|
+
props['zfsmgmt:snapshot'] == 'true' or
|
320
|
+
( props['zfsmgmt:snapshot'] == 'recursive' and props['zfsmgmt:snapshot@source'] == 'local' ) or
|
321
|
+
( props['zfsmgmt:snapshot'] == 'local' and props['zfsmgmt:snapshot@source'] == 'local' )
|
322
|
+
|
311
323
|
prefix = ( props.has_key?('zfsmgmt:snap_prefix') ? props['zfsmgmt:snap_prefix'] : 'zfsmgmt' )
|
312
324
|
ts = ( props.has_key?('zfsmgmt:snap_timestamp') ? props['zfsmgmt:snap_timestamp'] : '%FT%T%z' )
|
313
325
|
com = ['zfs','snapshot']
|
@@ -321,3 +333,26 @@ module ZfsMgmt
|
|
321
333
|
end
|
322
334
|
end
|
323
335
|
end
|
336
|
+
class ZfsMgmtList < Thor
|
337
|
+
class_option :filter, :type => :string, :default => '.+',
|
338
|
+
:desc => 'only act on zfs matching this regexp'
|
339
|
+
desc "stale", "list all zfs with stale snapshots"
|
340
|
+
method_option :age, :desc => "timeframe outside of which the zfs will be considered stale", :default => '1d'
|
341
|
+
def stale()
|
342
|
+
cutoff = Time.at(Time.now.to_i - ZfsMgmt.timespec_to_seconds(options[:age]))
|
343
|
+
table = Text::Table.new
|
344
|
+
table.head = ['zfs','snapshot','age']
|
345
|
+
table.rows = []
|
346
|
+
ZfsMgmt.zfs_managed_list(filter: options[:filter]).each do |blob|
|
347
|
+
zfs,props,snaps = blob
|
348
|
+
last = snaps.keys.sort { |a,b| snaps[a]['creation'] <=> snaps[b]['creation'] }.last
|
349
|
+
snap_time = Time.at(snaps[last]['creation'])
|
350
|
+
if snap_time < cutoff
|
351
|
+
table.rows << [zfs,last.split('@')[1],snap_time]
|
352
|
+
end
|
353
|
+
end
|
354
|
+
if table.rows.count > 0
|
355
|
+
print table.to_s
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module ZfsMgmt::Restic
|
3
|
+
def self.backup(backup_type: 'incremental', force: false, filter: '.+')
|
4
|
+
pp backup_type, force, filter
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class ZfsMgmtResticBackup < Thor
|
9
|
+
class_option :filter, :type => :string, :default => '.+',
|
10
|
+
:desc => 'only act on zfs matching this regexp'
|
11
|
+
class_option :force, :type => :boolean, :default => false,
|
12
|
+
:desc => 'force create this backup type, fail if it cannot be forced'
|
13
|
+
desc "incremental", "perform incremental backup"
|
14
|
+
def incremental()
|
15
|
+
ZfsMgmt::Restic.backup(backup_type: 'incremental', force: options[:force])
|
16
|
+
end
|
17
|
+
desc "differential", "perform differential backup"
|
18
|
+
def differential()
|
19
|
+
ZfsMgmt::Restic.backup(backup_type: 'differential', force: options[:force])
|
20
|
+
end
|
21
|
+
desc "full", "perform full backup"
|
22
|
+
def full()
|
23
|
+
ZfsMgmt::Restic.backup(backup_type: 'full', force: options[:force])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ZfsMgmtRestic < Thor
|
28
|
+
desc "restic SUBCOMMAND ...ARGS", "backup all configured zfs to restic"
|
29
|
+
subcommand "backup", ZfsMgmtResticBackup
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
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.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aran Cox
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-13 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
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- bin/zfssendman
|
126
126
|
- bin/zfssnapman
|
127
127
|
- lib/zfs_mgmt.rb
|
128
|
+
- lib/zfs_mgmt/restic.rb
|
128
129
|
- lib/zfs_mgmt/version.rb
|
129
130
|
- zfs_mgmt.gemspec
|
130
131
|
homepage: https://github.com/aranc23/zfs_mgmt
|
@@ -149,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
150
|
- !ruby/object:Gem::Version
|
150
151
|
version: '0'
|
151
152
|
requirements: []
|
152
|
-
rubygems_version: 3.
|
153
|
+
rubygems_version: 3.1.2
|
153
154
|
signing_key:
|
154
155
|
specification_version: 4
|
155
156
|
summary: Misc. helpers regarding snapshots and send/recv.
|