bakman 0.0.0 → 1.0.0
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.
- data/lib/bakman/backup.rb +26 -0
- data/lib/bakman/backuplist.rb +127 -0
- data/lib/bakman.rb +2 -103
- metadata +3 -1
@@ -0,0 +1,26 @@
|
|
1
|
+
# This classe require date to manipulate backup date and compare age between backups
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
|
5
|
+
# This class represent one backup of "something"
|
6
|
+
class Backup
|
7
|
+
|
8
|
+
# One backup refers to the #filepath that contains that backup.
|
9
|
+
# That file has to be represented by #{name_of_something}_#{date}
|
10
|
+
# The #date has to be represented this way : %Y%m%dT%H%M
|
11
|
+
attr_reader :filepath, :date
|
12
|
+
attr_accessor :to_keep
|
13
|
+
|
14
|
+
# create one instance of Backup with the #filepath
|
15
|
+
def initialize(filepath)
|
16
|
+
@filepath = filepath
|
17
|
+
@date = Date.strptime(filepath[/\d{8}T\d{4}/],'%Y%m%dT%H%M')
|
18
|
+
@to_keep = false
|
19
|
+
end
|
20
|
+
|
21
|
+
# delete that backup (you could need that if the backup is too old)
|
22
|
+
def delete!
|
23
|
+
puts "#{filepath} deleted."
|
24
|
+
File.delete(filepath)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# This classe require date to manipulate backup date and compare age between backups
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
# This class handles a collection of #Backup for the same object "something".
|
5
|
+
# This is useful to manipulate backups as a whole
|
6
|
+
class BackupList < Array
|
7
|
+
|
8
|
+
# The object you want to manage the backups has
|
9
|
+
# * a #name
|
10
|
+
# * the backups are saved in a #folder
|
11
|
+
attr_reader :name, :folder, :lenght
|
12
|
+
|
13
|
+
# This is populating the array with #Backup objects
|
14
|
+
# It is sorted at the end for later manipulation on a date sorted array.
|
15
|
+
def create(folder,name)
|
16
|
+
@name = name
|
17
|
+
@folder = folder
|
18
|
+
@lenght = 0
|
19
|
+
list = Dir.glob("#{folder}/#{name}*")
|
20
|
+
list.each do |path|
|
21
|
+
self << Backup.new(path)
|
22
|
+
@lenght += 1
|
23
|
+
end
|
24
|
+
self.sort_by! {|bck| bck.date}
|
25
|
+
end
|
26
|
+
|
27
|
+
# A short method to print the list of backups
|
28
|
+
def list
|
29
|
+
puts "The list of backups for #{self.name}"
|
30
|
+
self.each do |bck|
|
31
|
+
puts bck.filepath
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# A method to determine if a backup has to be kept or not.
|
36
|
+
# We go thru the array in the reverse order. It allows to test the more recent entries first and keep them first.
|
37
|
+
# To be kept, a backup needs :
|
38
|
+
# * to have his ( #Backup.date ) between #down_date and #up_date
|
39
|
+
# * to be more recent
|
40
|
+
# * to not be already kept
|
41
|
+
# It returns nb_kept for post analyses
|
42
|
+
def keep_backup(nb_to_keep,down_date, up_date)
|
43
|
+
range = down_date..up_date
|
44
|
+
nb_kept = 0
|
45
|
+
self.reverse_each do |bck|
|
46
|
+
if range === bck.date
|
47
|
+
if nb_kept < nb_to_keep
|
48
|
+
if bck.to_keep != true
|
49
|
+
puts "#{bck.filepath} will be kept!"
|
50
|
+
bck.to_keep = true
|
51
|
+
nb_kept += 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
return nb_kept
|
57
|
+
end
|
58
|
+
|
59
|
+
# A useful method to rotate the files
|
60
|
+
# * #nb_to_keep is the number of backups to keep betwwen the two #down_date and #up_date
|
61
|
+
# (number above #number_to_keep will be deleted)
|
62
|
+
def rotate(nb_to_keep, down_date, up_date)
|
63
|
+
nb_kept = keep_backup(nb_to_keep,down_date, up_date)
|
64
|
+
|
65
|
+
if nb_kept == nb_to_keep
|
66
|
+
puts "There is enough backups for this time period."
|
67
|
+
else
|
68
|
+
puts "Not enough backups between #{down_date} and #{up_date}."
|
69
|
+
if up_date == Date.today
|
70
|
+
puts "Instead of #{nb_to_keep} backup(s), you will have #{nb_kept} backup(s)"
|
71
|
+
else
|
72
|
+
puts "We will look for a closer period to find backups if possible."
|
73
|
+
self.reverse.rotate(nb_to_keep - nb_kept, up_date, Date.today)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# a redefinition of the reverse method from the parent class array
|
79
|
+
def reverse
|
80
|
+
reversed = BackupList.new
|
81
|
+
self.reverse_each do |bck|
|
82
|
+
reversed << bck
|
83
|
+
end
|
84
|
+
return reversed
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# A quick method to clean backups files, the one that are not to be kept ( Backup.to_keep == false )
|
89
|
+
def clean_bck!
|
90
|
+
self.each do |bck|
|
91
|
+
if bck.to_keep == false
|
92
|
+
bck.delete!
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# A method to do an automatic GrandFather Father Son rotation of the backups
|
98
|
+
# Here a month is 30 days
|
99
|
+
# * #nb_g is the number of GrandFather backups to keep (Monthly)
|
100
|
+
# * #nb_f is the number of Father backups to keep (weekly)
|
101
|
+
# * #nb_s is the number of son backups to keep (daily)
|
102
|
+
#/!\ It checks until the prev year but not before.
|
103
|
+
def rotate_gfs!(nb_g, nb_f, nb_s)
|
104
|
+
|
105
|
+
puts "Rotate GrandFather"
|
106
|
+
self.rotate(nb_g,Date.today.prev_year, Date.today.prev_day(30))
|
107
|
+
|
108
|
+
puts "Rotate Father"
|
109
|
+
self.rotate(nb_f,Date.today.prev_day(29), Date.today.prev_day(7))
|
110
|
+
|
111
|
+
puts "Rotate Son"
|
112
|
+
self.rotate(nb_s,Date.today.prev_day(6),Date.today)
|
113
|
+
|
114
|
+
puts "Remove unecessary backups"
|
115
|
+
self.clean_bck!
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
# A method to rsync the backup folder with a remote host describe by #host
|
120
|
+
# #host should be username@machine
|
121
|
+
# the ssh_keys have to be exchanged before using this (if not, it will failed)
|
122
|
+
# /!\ the folder has to exist on the remote host.
|
123
|
+
def rsync!(host, remote_folder)
|
124
|
+
puts "rsync #{folder}/#{name}* #{host}:#{remote_folder}"
|
125
|
+
`rsync #{folder}/#{name}* #{host}:#{remote_folder}`
|
126
|
+
end
|
127
|
+
end
|
data/lib/bakman.rb
CHANGED
@@ -1,103 +1,2 @@
|
|
1
|
-
|
2
|
-
require '
|
3
|
-
|
4
|
-
# This class represent one backup of "something"
|
5
|
-
class Backup
|
6
|
-
|
7
|
-
# One backup refers to the #filepath that contains that backup.
|
8
|
-
# That file has to be represented by #{name_of_something}_#{date}
|
9
|
-
# The #date has to be represented this way : %Y%m%dT%H%M
|
10
|
-
attr_reader :filepath, :date
|
11
|
-
|
12
|
-
# create one instance of Backup with the #filepath
|
13
|
-
def initialize(filepath)
|
14
|
-
@filepath = filepath
|
15
|
-
@date = Date.strptime(filepath[/\d{8}T\d{4}/],'%Y%m%dT%H%M')
|
16
|
-
end
|
17
|
-
|
18
|
-
# delete that backup (you could need that if the backup is too old)
|
19
|
-
def delete!
|
20
|
-
puts "#{filepath} deleted."
|
21
|
-
File.delete(filepath)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
|
-
# This class handles a collection of #Backup for the same object "something".
|
27
|
-
# This is useful to manipulate backups as a whole
|
28
|
-
class BackupList < Array
|
29
|
-
|
30
|
-
# The object you want to manage the backups has
|
31
|
-
# * a #name
|
32
|
-
# * the backups are saved in a #folder
|
33
|
-
attr_reader :name, :folder
|
34
|
-
|
35
|
-
# This is populating the array with #Backup objects
|
36
|
-
# It is sorted at the end for later manipulation on a date sorted array.
|
37
|
-
def initialize(folder,name)
|
38
|
-
@name = name
|
39
|
-
@folder = folder
|
40
|
-
list = Dir.glob("#{folder}/#{name}*")
|
41
|
-
list.each do |path|
|
42
|
-
self << Backup.new(path)
|
43
|
-
end
|
44
|
-
self.sort_by! {|bck| bck.date}
|
45
|
-
end
|
46
|
-
|
47
|
-
# A short method to print the list of backups
|
48
|
-
def list
|
49
|
-
puts "The list of backups for #{self.name}"
|
50
|
-
self.each do |bck|
|
51
|
-
puts bck.filepath
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# A useful method to rotate the files
|
56
|
-
# * #nb_to_keep is the number of backups to keep betwwen the two #down_date and #up_date
|
57
|
-
# (number above #number_to_keep will be deleted)
|
58
|
-
def rotate!(nb_to_keep, down_date, up_date)
|
59
|
-
range = down_date..up_date
|
60
|
-
list = []
|
61
|
-
self.each do |bck|
|
62
|
-
list << bck if range === bck.date
|
63
|
-
end
|
64
|
-
|
65
|
-
if list.length == 0
|
66
|
-
puts "No backup between #{down_date} and #{up_date}."
|
67
|
-
elsif list.length <= nb_to_keep
|
68
|
-
puts "There is no need to delete backups."
|
69
|
-
else
|
70
|
-
nb_to_delete = list.length - nb_to_keep
|
71
|
-
puts "#{nb_to_keep} backup(s) will be kept and #{nb_to_delete} backup(s) will be deleted."
|
72
|
-
list.pop(nb_to_keep)
|
73
|
-
list.each {|bck| bck.delete!}
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# A method to do an automatic GrandFather Father Son rotation of the backups
|
78
|
-
# Here a month is 30 days
|
79
|
-
# * #nb_g is the number of GrandFather backups to keep (Monthly)
|
80
|
-
# * #nb_f is the number of Father backups to keep (weekly)
|
81
|
-
# * #nb_s is the number of son backups to keep (daily)
|
82
|
-
#/!\ It checks until the prev year but not before.
|
83
|
-
def rotate_gfs!(nb_g, nb_f, nb_s)
|
84
|
-
|
85
|
-
puts "Rotate GrandFather"
|
86
|
-
self.rotate!(nb_g,Date.today.prev_year, Date.today.prev_day(30))
|
87
|
-
|
88
|
-
puts "Rotate Father"
|
89
|
-
self.rotate!(nb_f,Date.today.prev_day(29), Date.today.prev_day(7))
|
90
|
-
|
91
|
-
puts "Rotate Son"
|
92
|
-
self.rotate!(nb_s,Date.today.prev_day(6),Date.today)
|
93
|
-
|
94
|
-
end
|
95
|
-
# A method to rsync the backup folder with a remote host describe by #host
|
96
|
-
# #host should be username@machine
|
97
|
-
# the ssh_keys have to be exchanged before using this (if not, it will failed)
|
98
|
-
# /!\ the folder has to exist on the remote host.
|
99
|
-
def rsync!(host, remote_folder)
|
100
|
-
puts "rsync #{folder}/#{name}* #{host}:#{remote_folder}"
|
101
|
-
`rsync #{folder}/#{name}* #{host}:#{remote_folder}`
|
102
|
-
end
|
103
|
-
end
|
1
|
+
require 'bakman/backup.rb'
|
2
|
+
require 'bakman/backuplist.rb'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bakman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -19,6 +19,8 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- lib/bakman.rb
|
22
|
+
- lib/bakman/backup.rb
|
23
|
+
- lib/bakman/backuplist.rb
|
22
24
|
homepage: http://rubygems.org/gems/bakman
|
23
25
|
licenses: []
|
24
26
|
post_install_message:
|