remotebackup 0.50.7 → 0.50.8

Sign up to get free protection for your applications and to get access to all the features.
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