remotebackup 0.50.7 → 0.50.8

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.
Files changed (2) hide show
  1. data/lib/remotebackup.rb +290 -291
  2. metadata +3 -3
data/lib/remotebackup.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
  require 'rubygems'
4
4
  require 'net/ssh'
5
5
  require 'net/scp'
@@ -10,297 +10,296 @@ require "date"
10
10
  require 'logger'
11
11
  require 'yaml'
12
12
  module Remotebackup
13
- VERSION='0.50.7'
14
- class Node
15
- attr_accessor :ftype,:name,:makeMap
16
- LS_FILE = /([-a-z]*)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d*)\s+([A-Z][a-z]*)\s+(\d+)\s+([\d:]*)\s+(.*)/
17
- LS_LINK = /([-a-z]*)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d*)\s+([A-Z][a-z]*)\s+(\d+)\s+([\d:]*)\s+(.*)\s+->\s+(.*)/
18
- Result = {:access=>0,:link_num=>1,:user=>2,:group=>3,:size=>4,:month=>5,:day=>6,:yt=>7,:name=>8,:arrow=>9,:source=>10}
19
- Month = {"Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6, "Jul" => 7, "Aug" => 8,
20
- "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12}
21
-
22
- def initialize(out)
23
- if out =~ /[^\x20-\x7E]/
24
- $log.error("#{out} includes irregular char. ignore.")
25
- return
26
- end
27
- case out
28
- when /^-/
29
- if LS_FILE.match(out)
30
- @name = $9
31
- @ftype = :file
32
- @size = $5.to_i
33
- month = Month[$6]
34
- day = $7.to_i
35
- hour = 0
36
- minute = 0
37
- tmpTime = $8
38
- if tmpTime =~ /(.*):(.*)/
39
- year = DateTime.now.year
40
- hour = $1.to_i
41
- minute = $2.to_i
42
- else
43
- year = tmpTime.to_i
44
- end
45
- @date = DateTime.new(year,month,day,hour,minute).to_s
46
- @makeMap = lambda{ return {"size" => @size, "date" => @date}}
47
- else
48
- $log.error("#{out} is not recognized. ignore.")
49
- end
50
- when /^l/
51
- if LS_LINK.match(out)
52
- @name = $9
53
- @ftype = :symbolic
54
- @source = $10
55
- @makeMap = lambda{ return {"source" => @source}}
56
- end
57
- when /^d/
58
- if LS_FILE.match(out)
59
- @name = $9
60
- @ftype = :directory
61
- end
62
- else
63
- @ftype = :special
64
- $log.error("#{out} is not regular file. ignore.")
65
- end
66
- end
67
- end
68
- class BackupInfo
69
- attr_accessor :fileMap,:mod,:last_file
70
- def initialize(name,server,user,password,path,ignore_list)
71
- @mod = false
72
- @name = name
73
- @server = server
74
- @user = user
75
- @password = password
76
- @path = path
77
- @ignore_list = ignore_list
78
- @nowTime = DateTime.now
79
- @fileMap = {"file" => Hash.new,"symbolic" => Hash.new,"directory"=>Array.new}
80
- Net::SSH.start(@server,@user,:password=>@password) { |session|
81
- makeFileMapList(session,"")
82
- }
83
- end
84
- def ignore_check(target)
85
- if @ignore_list
86
- @ignore_list.each do |ignore|
87
- if target =~ /#{ignore}/
88
- return false
89
- end
90
- end
91
- end
92
- return true
93
- end
94
- def makeFileMapList(session,target)
95
- if target != ""
96
- target_path = @path +"/"+target
97
- else
98
- target_path = @path
99
- end
100
- cmd = "export LANG=C;ls -la #{target_path}"
101
- out = ""
102
- channel = session.open_channel do |ch|
103
- ch.exec cmd do |ch,success|
104
- ch.on_data do |c,data|
105
- out += data
106
- end
107
- end
108
- end
109
- channel.wait
110
- if out =~ /No such file/
111
- $log.error("can't open path:#{target_path}")
112
- return
113
- end
114
- if out == ""
115
- return
116
- end
117
- lines = StringIO.new(out).readlines
118
- if lines[0].split().length < 9
119
- @fileMap["directory"].push target unless target == ""
120
- makeFileMap(session,target,lines)
121
- else
122
- node = Node.new(lines[0].chomp)
123
- if node.ftype == :symbolic
124
- @fileMap["symbolic"][File.basename(@path)] = node.makeMap.call
125
- elsif node.ftype == :file
126
- @fileMap["file"][File.basename(@path)] = node.makeMap.call
127
- end
128
- end
129
- end
130
- def makeFileMap(session,target,lines)
131
- lines.each do |line|
132
- if line.split().length < 9
133
- next
134
- end
135
- node = Node.new(line.chomp)
136
- if not node.name or node.name == "." or node.name == ".."
137
- next
138
- end
139
- if target != ""
140
- target_name = target +"/"+ node.name
141
- else
142
- target_name = node.name
143
- end
144
- unless ignore_check(target_name)
145
- next
146
- end
147
- case node.ftype
148
- when :directory
149
- makeFileMapList(session,target_name)
150
- when :special
151
- next
152
- when :file
153
- @fileMap["file"][target_name] = node.makeMap.call
154
- when :symbolic
155
- @fileMap["symbolic"][target_name] = node.makeMap.call
156
- end
157
- end
158
- end
159
- def outputYaml(out_dir)
160
- output_dir = out_dir + "/" + @name
161
- f = output_dir + "/" + date_to_filename + ".yml"
162
- File.open(f,"w") do |f|
163
- f.write YAML.dump(@fileMap)
164
- end
13
+ VERSION='0.50.8'
14
+ class Node
15
+ attr_accessor :ftype,:name,:makeMap
16
+ LS_FILE = /([-a-z]*)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d*)\s+([A-Z][a-z]*)\s+(\d+)\s+([\d:]*)\s+(.*)/
17
+ LS_LINK = /([-a-z]*)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d*)\s+([A-Z][a-z]*)\s+(\d+)\s+([\d:]*)\s+(.*)\s+->\s+(.*)/
18
+ Result = {:access=>0,:link_num=>1,:user=>2,:group=>3,:size=>4,:month=>5,:day=>6,:yt=>7,:name=>8,:arrow=>9,:source=>10}
19
+ Month = {"Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6, "Jul" => 7, "Aug" => 8,
20
+ "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12}
21
+
22
+ def initialize(out)
23
+ if out =~ /[^\x20-\x7E]/
24
+ $log.error("#{out} includes irregular char. ignore.")
25
+ return
26
+ end
27
+ case out
28
+ when /^-/
29
+ if LS_FILE.match(out)
30
+ @name = $9
31
+ @ftype = :file
32
+ @size = $5.to_i
33
+ month = Month[$6]
34
+ day = $7.to_i
35
+ hour = 0
36
+ minute = 0
37
+ tmpTime = $8
38
+ if tmpTime =~ /(.*):(.*)/
39
+ year = DateTime.now.year
40
+ hour = $1.to_i
41
+ minute = $2.to_i
42
+ else
43
+ year = tmpTime.to_i
44
+ end
45
+ @date = DateTime.new(year,month,day,hour,minute).to_s
46
+ @makeMap = lambda{ return {"size" => @size, "date" => @date}}
47
+ else
48
+ $log.error("#{out} is not recognized. ignore.")
49
+ end
50
+ when /^l/
51
+ if LS_LINK.match(out)
52
+ @name = $9
53
+ @ftype = :symbolic
54
+ @source = $10
55
+ @makeMap = lambda{ return {"source" => @source}}
56
+ end
57
+ when /^d/
58
+ if LS_FILE.match(out)
59
+ @name = $9
60
+ @ftype = :directory
61
+ end
62
+ else
63
+ @ftype = :special
64
+ $log.error("#{out} is not regular file. ignore.")
65
+ end
66
+ end
67
+ end
68
+ class BackupInfo
69
+ attr_accessor :fileMap,:mod,:last_file
70
+ def initialize(name,server,user,password,path,ignore_list)
71
+ @mod = false
72
+ @name = name
73
+ @server = server
74
+ @user = user
75
+ @password = password
76
+ @path = path
77
+ @ignore_list = ignore_list
78
+ @nowTime = DateTime.now
79
+ @fileMap = {"file" => Hash.new,"symbolic" => Hash.new,"directory"=>Array.new}
80
+ Net::SSH.start(@server,@user,:password=>@password) { |session|
81
+ makeFileMapList(session,"")
82
+ }
83
+ end
84
+ def ignore_check(target)
85
+ if @ignore_list
86
+ @ignore_list.each do |ignore|
87
+ if target =~ /#{ignore}/
88
+ return false
89
+ end
90
+ end
91
+ end
92
+ return true
93
+ end
94
+ def makeFileMapList(session,target)
95
+ if target != ""
96
+ target_path = @path +"/"+target
97
+ else
98
+ target_path = @path
99
+ end
100
+ cmd = "export LANG=C;ls -la #{target_path}"
101
+ out = ""
102
+ channel = session.open_channel do |ch|
103
+ ch.exec cmd do |ch,success|
104
+ ch.on_data do |c,data|
105
+ out += data
106
+ end
107
+ end
108
+ end
109
+ channel.wait
110
+ if out =~ /No such file/
111
+ $log.error("can't open path:#{target_path}")
112
+ return
113
+ end
114
+ if out == ""
115
+ return
116
+ end
117
+ lines = StringIO.new(out).readlines
118
+ if lines[0].split().length < 9
119
+ @fileMap["directory"].push target unless target == ""
120
+ makeFileMap(session,target,lines)
121
+ else
122
+ node = Node.new(lines[0].chomp)
123
+ if node.ftype == :symbolic
124
+ @fileMap["symbolic"][File.basename(@path)] = node.makeMap.call
125
+ elsif node.ftype == :file
126
+ @fileMap["file"][File.basename(@path)] = node.makeMap.call
127
+ end
128
+ end
129
+ end
130
+ def makeFileMap(session,target,lines)
131
+ lines.each do |line|
132
+ if line.split().length < 9
133
+ next
134
+ end
135
+ node = Node.new(line.chomp)
136
+ if not node.name or node.name == "." or node.name == ".."
137
+ next
138
+ end
139
+ if target != ""
140
+ target_name = target +"/"+ node.name
141
+ else
142
+ target_name = node.name
165
143
  end
166
- def cleanFileInfo()
167
- FileUtils.touch([@last_file])
144
+ unless ignore_check(target_name)
145
+ next
168
146
  end
169
- def load_last_yaml(output_dir)
170
- files = Array.new
171
- if FileTest.directory?(output_dir)
172
- dirs = Dir.glob(output_dir+ "/*.yml")
173
- dirs.each do |file|
174
- files.push file
175
- end
176
- end
177
- if files.length == 0
178
- return {"file" => Hash.new,"symbolic" => Hash.new,"directory"=>Array.new}
179
- end
180
- @last_file = files.sort.pop
181
- return YAML.load(File.read(@last_file))
182
- end
183
- def differencial_copy(out_dir)
184
- output_dir = out_dir + "/" + @name
185
- oldFileInfoMap = load_last_yaml(output_dir)
186
- @fileMap["directory"].each do |dir|
187
- unless oldFileInfoMap["directory"].include?(dir)
188
- @mod = true
189
- msg_out "create directory:#{dir}"
190
- FileUtils.mkdir_p(output_dir + "/" + dir)
191
- end
192
- end
193
- oldFileMap = oldFileInfoMap["symbolic"]
194
- @fileMap["symbolic"].each do |key,val|
195
- if !oldFileMap[key] || oldFileMap[key]["source"] != val["source"]
196
- @mod = true
197
- if !oldFileMap[key]
198
- msg_out "create symbolic:#{key}"
199
- else
200
- msg_out "modified symbolic:#{key}"
201
- end
202
- end
203
- end
204
- oldFileMap = oldFileInfoMap["file"]
205
- Net::SSH.start(@server, @user, :password => @password) do |ssh|
206
- @fileMap["file"].each do |key,val|
207
- if !oldFileMap[key] || oldFileMap[key]["date"] != val["date"]
208
- @mod = true
209
- file_name = output_dir + "/" + key + date_to_filename
210
- orig = "#{@path}/#{key}".gsub(/ /,"\\ ")
211
- dest = file_name.gsub(/ /,"\\ ")
212
- msg_out "scp #{orig} #{dest}"
213
- ssh.scp.download!(orig,dest)
214
- val["file_name"] = dest
215
- if !oldFileMap[key]
216
- msg_out "create file:#{key}"
217
- else
218
- msg_out "modified file:#{key}"
219
- end
220
- else
221
- val["file_name"] = oldFileMap[key]["file_name"]
222
- end
223
- end
147
+ case node.ftype
148
+ when :directory
149
+ makeFileMapList(session,target_name)
150
+ when :special
151
+ next
152
+ when :file
153
+ @fileMap["file"][target_name] = node.makeMap.call
154
+ when :symbolic
155
+ @fileMap["symbolic"][target_name] = node.makeMap.call
156
+ end
157
+ end
158
+ end
159
+ def outputYaml(out_dir)
160
+ output_dir = out_dir + "/" + @name
161
+ f = output_dir + "/" + date_to_filename + ".yml"
162
+ File.open(f,"w") do |f|
163
+ f.write YAML.dump(@fileMap)
164
+ end
165
+ end
166
+ def cleanFileInfo()
167
+ FileUtils.touch([@last_file])
168
+ end
169
+ def load_last_yaml(output_dir)
170
+ files = Array.new
171
+ if FileTest.directory?(output_dir)
172
+ dirs = Dir.glob(output_dir+ "/*.yml")
173
+ dirs.each do |file|
174
+ files.push file
175
+ end
176
+ end
177
+ if files.length == 0
178
+ return {"file" => Hash.new,"symbolic" => Hash.new,"directory"=>Array.new}
179
+ end
180
+ @last_file = files.sort.pop
181
+ return YAML.load(File.read(@last_file))
182
+ end
183
+ def differencial_copy(out_dir)
184
+ output_dir = out_dir + "/" + @name
185
+ FileUtils.mkdir_p(output_dir)
186
+ oldFileInfoMap = load_last_yaml(output_dir)
187
+ @fileMap["directory"].each do |dir|
188
+ unless oldFileInfoMap["directory"].include?(dir)
189
+ @mod = true
190
+ msg_out "create directory:#{dir}"
191
+ FileUtils.mkdir_p(output_dir + "/" + dir)
192
+ end
193
+ end
194
+ oldFileMap = oldFileInfoMap["symbolic"]
195
+ @fileMap["symbolic"].each do |key,val|
196
+ if !oldFileMap[key] || oldFileMap[key]["source"] != val["source"]
197
+ @mod = true
198
+ if !oldFileMap[key]
199
+ msg_out "create symbolic:#{key}"
200
+ else
201
+ msg_out "modified symbolic:#{key}"
202
+ end
203
+ end
204
+ end
205
+ oldFileMap = oldFileInfoMap["file"]
206
+ Net::SSH.start(@server, @user, :password => @password) do |ssh|
207
+ @fileMap["file"].each do |key,val|
208
+ if !oldFileMap[key] || oldFileMap[key]["date"] != val["date"]
209
+ @mod = true
210
+ file_name = output_dir + "/" + key + date_to_filename
211
+ orig = "#{@path}/#{key}".gsub(/ /,"\\ ")
212
+ msg_out "scp #{orig} #{file_name}"
213
+ ssh.scp.download!(orig,file_name)
214
+ val["file_name"] = file_name
215
+ if !oldFileMap[key]
216
+ msg_out "create file:#{key}"
217
+ else
218
+ msg_out "modified file:#{key}"
224
219
  end
225
- end
226
- def zerosup(i)
227
- if i < 10
228
- "0" + i.to_s
229
- else
230
- i.to_s
231
- end
232
- end
233
- def date_to_filename()
234
- @nowTime.year.to_s + "_" + zerosup(@nowTime.month) + "_" + zerosup(@nowTime.day) + "_" + zerosup(@nowTime.hour) + "_" + zerosup(@nowTime.min)
235
- end
236
- end
237
- class Backup
238
- def initialize(config_file,config_out_dir)
239
- @config_file = config_file
240
- @config_out_dir = config_out_dir
241
- @doc = REXML::Document.new(File.open(@config_file))
242
- @top = @doc.elements["/backups"]
243
- @conf_backups = Array.new
244
- unless @top
245
- oops("/backups is not set in #{@config_file}.")
246
- end
247
- @top.each_element do |backup|
248
- bkup_info = Hash.new
249
- backup.each_element do |elem|
250
- if elem.name == "ignore_list"
251
- ignores = Array.new
252
- elem.each_element do |ignore|
253
- if ignore.text
254
- ignores.push(ignore.text)
255
- end
256
- end
257
- bkup_info["ignore_list"] = ignores
258
- else
259
- bkup_info[elem.name] = elem.text
260
- end
261
- end
262
- @conf_backups.push(bkup_info)
263
- end
264
- end
265
- def start
266
- i=1
267
- @conf_backups.each do |conf|
268
- bkup = BackupInfo.new(conf["name"],conf["server"],conf["user"],conf["password"],conf["path"],conf["ignore_list"])
269
- msg_out "--------------------------------"
270
- msg_out "Backup start #{conf['name']}"
271
- msg_out "--------------------------------"
272
- bkup.differencial_copy(@config_out_dir)
273
- if bkup.mod
274
- bkup.outputYaml(@config_out_dir)
275
- else
276
- bkup.cleanFileInfo()
277
- end
278
- end
279
- end
280
- end
281
- class Restore
282
- def initialize(config_file,config_out_dir)
283
- @config_file = config_file
284
- @file_info_map = YAML.load_file(config_file)
285
- @config_out_dir = config_out_dir
286
- FileUtils.mkdir_p(@config_out_dir)
287
- end
288
- def start
289
- msg_out "-------------------------------------------"
290
- msg_out "Restore start #{File.dirname(@config_file)}"
291
- msg_out "-------------------------------------------"
292
- @file_info_map["directory"].each do |dir|
293
- msg_out "mkdir -p #{@config_out_dir}/#{dir}"
294
- FileUtils.mkdir_p(@config_out_dir + "/" + dir)
295
- end
296
- @file_info_map["symbolic"].each do |key,val|
297
- msg_out "link -s #{val['source']} #{@config_out_dir}/#{key}"
298
- FileUtils.symlink(val["source"],@config_out_dir + "/" + key)
299
- end
300
- @file_info_map["file"].each do |key,val|
301
- msg_out "cp #{val['file_name']} #{@config_out_dir}/#{key}"
302
- FileUtils.cp(val["file_name"],@config_out_dir + "/" + key)
303
- end
304
- end
305
- end
220
+ else
221
+ val["file_name"] = oldFileMap[key]["file_name"]
222
+ end
223
+ end
224
+ end
225
+ end
226
+ def zerosup(i)
227
+ if i < 10
228
+ "0" + i.to_s
229
+ else
230
+ i.to_s
231
+ end
232
+ end
233
+ def date_to_filename()
234
+ @nowTime.year.to_s + "_" + zerosup(@nowTime.month) + "_" + zerosup(@nowTime.day) + "_" + zerosup(@nowTime.hour) + "_" + zerosup(@nowTime.min)
235
+ end
236
+ end
237
+ class Backup
238
+ def initialize(config_file,config_out_dir)
239
+ @config_file = config_file
240
+ @config_out_dir = config_out_dir
241
+ @doc = REXML::Document.new(File.open(@config_file))
242
+ @top = @doc.elements["/backups"]
243
+ @conf_backups = Array.new
244
+ unless @top
245
+ oops("/backups is not set in #{@config_file}.")
246
+ end
247
+ @top.each_element do |backup|
248
+ bkup_info = Hash.new
249
+ backup.each_element do |elem|
250
+ if elem.name == "ignore_list"
251
+ ignores = Array.new
252
+ elem.each_element do |ignore|
253
+ if ignore.text
254
+ ignores.push(ignore.text)
255
+ end
256
+ end
257
+ bkup_info["ignore_list"] = ignores
258
+ else
259
+ bkup_info[elem.name] = elem.text
260
+ end
261
+ end
262
+ @conf_backups.push(bkup_info)
263
+ end
264
+ end
265
+ def start
266
+ @conf_backups.each do |conf|
267
+ bkup = BackupInfo.new(conf["name"],conf["server"],conf["user"],conf["password"],conf["path"],conf["ignore_list"])
268
+ msg_out "--------------------------------"
269
+ msg_out "Backup start #{conf['name']}"
270
+ msg_out "--------------------------------"
271
+ bkup.differencial_copy(@config_out_dir)
272
+ if bkup.mod
273
+ bkup.outputYaml(@config_out_dir)
274
+ else
275
+ bkup.cleanFileInfo()
276
+ end
277
+ end
278
+ end
279
+ end
280
+ class Restore
281
+ def initialize(config_file,config_out_dir)
282
+ @config_file = config_file
283
+ @file_info_map = YAML.load_file(config_file)
284
+ @config_out_dir = config_out_dir
285
+ FileUtils.mkdir_p(@config_out_dir)
286
+ end
287
+ def start
288
+ msg_out "-------------------------------------------"
289
+ msg_out "Restore start #{File.dirname(@config_file)}"
290
+ msg_out "-------------------------------------------"
291
+ @file_info_map["directory"].each do |dir|
292
+ msg_out "mkdir -p #{@config_out_dir}/#{dir}"
293
+ FileUtils.mkdir_p(@config_out_dir + "/" + dir)
294
+ end
295
+ @file_info_map["symbolic"].each do |key,val|
296
+ msg_out "link -s #{val['source']} #{@config_out_dir}/#{key}"
297
+ FileUtils.symlink(val["source"],@config_out_dir + "/" + key)
298
+ end
299
+ @file_info_map["file"].each do |key,val|
300
+ msg_out "cp #{val['file_name']} #{@config_out_dir}/#{key}"
301
+ FileUtils.cp(val["file_name"],@config_out_dir + "/" + key)
302
+ end
303
+ end
304
+ end
306
305
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remotebackup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.50.7
4
+ version: 0.50.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - takeshi morita
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-21 00:00:00 -05:00
12
+ date: 2008-11-22 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
102
  requirements: []
103
103
 
104
104
  rubyforge_project: remotebackup
105
- rubygems_version: 1.3.1
105
+ rubygems_version: 1.2.0
106
106
  signing_key:
107
107
  specification_version: 2
108
108
  summary: remote ssh backup is backup files on remote server with ssh