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.
@@ -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
- # This set of classes require date to manipulate backup date and compare age between backups
2
- require 'date'
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: 0.0.0
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: