Project

General

Profile

Bug #1594 ยป trimMachines.rb

bdezonia (Barry DeZonia), 06/10/2009 02:24 AM

 
1

    
2
# trimMachines.rb
3

    
4
# using ruby to delete files older than X days
5
# w: gets mapped to source dir
6
# x: gets mapped to dest dir
7

    
8
DEBUGGING = false
9

    
10
ORIG_DRIVE = "w:"
11
COPY_DRIVE = "x:"
12

    
13
require "ftools"
14

    
15
DaysToKeep = 60
16
SecondsPerDay = 24 * 60 * 60
17
DaysToKeepInSeconds = DaysToKeep * SecondsPerDay
18

    
19
def loadCredentials
20
  $credentials = {}
21
  File.open("d:\\backupScripts\\directoryList.txt").each do | line |
22
    dataLine = line.chomp
23
    next if (dataLine.length > 0) and (dataLine[0].chr == "#")
24
    if dataLine =~ /(.*),(.*),(.*),(.*),(.*),(.*),(.*)/
25
      
26
      usr = $1
27
      psswd = $2
28
      machine = $3
29
      
30
      creds = []
31
      creds[0] = usr
32
      creds[1] = psswd
33
      $credentials[machine] = creds
34
    end
35
  end
36
end
37

    
38
# machineReady() : determines if machine is available on network
39
#    could be gone, off, have firewall misconfigured, other things
40

    
41
def machineReady(machine)
42
  ready = true
43

    
44
  begin
45
    TCPSocket.new(machine, 139).close
46
    TCPSocket.new(machine, 445).close
47
    s = UDPSocket.new
48
    s.connect(machine,137)
49
    s.close
50
    s = UDPSocket.new
51
    s.connect(machine,138)
52
    s.close
53
  rescue SocketError
54
    $logFile.print "#{machine} not found on network.\n"
55
    ready = false
56
  rescue Errno::EBADF
57
    $logFile.print "#{machine}'s file/print sharing ports not accessible.\n"
58
    ready = false
59
  rescue Errno::ETIMEDOUT
60
    $logFile.print "Contact with #{machine} timed out. Off?\n"
61
    ready = false
62
  rescue Errno::ECONNREFUSED
63
    $logFile.print "Connection with #{machine} refused.\n"
64
    ready = false
65
  end    
66
  ready
67
end
68
  
69
def decrypt(pss)
70
  outStr = ""
71
  pss.each_byte do | ch |
72
    if (ch > 79)  # 80 <= ch <= 126
73
      newCh = (ch - 47).chr
74
      #print "[#{ch.chr}] went to [#{newCh}]\n"
75
      outStr << newCh
76
    else # 33 <= ch <= 79
77
      newCh = (ch + 47).chr
78
      #print "[#{ch.chr}] went to [#{newCh}]\n"
79
      outStr << newCh
80
    end
81
  end
82
  outStr
83
end
84

    
85
def deleteFileIfNecessary(dirPath,file)
86
  origDirectory = ORIG_DRIVE + dirPath
87
    
88
  # on host: directory exists
89
  presentOnOrigMachine = File.directory?(origDirectory)
90
  
91
  # on host: file exists too
92
  presentOnOrigMachine = File.exist?(origDirectory+"\\"+file) if presentOnOrigMachine
93
    
94
  if not presentOnOrigMachine
95
    begin
96
      # if copy is more than NumDaysToSave days old
97
      copyOfFile = COPY_DRIVE + dirPath + "\\" + file
98
      if (Time.now - File.stat(copyOfFile).mtime) > DaysToKeepInSeconds
99
        $logFile.print "Deleting file #{copyOfFile}\n"
100
        File.rm_f(copyOfFile) if not DEBUGGING
101
      end
102
    rescue
103
      # do nothing so we can continue with other files
104
      #   can get here for a couple reasons
105
      #    1)  maybe: file deleted between time mtime called and rm_f called
106
      #    2)  certain if filename contains non-ascii chars: Ruby chokes with Errno::ENOENT
107
      #    maybe more
108
      $logFile.print "Deletion of #{copyOfFile} failed!\n"
109
    end
110
  end
111
end
112

    
113
def deleteDirectoryIfNecessary(dirPath,directory)
114
  copyOfDir = COPY_DRIVE + dirPath + "\\" + directory
115
  begin
116
    if (Dir.new(copyOfDir).entries.length <= 2)
117
       $logFile.print "Deleting directory #{copyOfDir}\n"
118
       Dir.delete(copyOfDir) if not DEBUGGING
119
    end
120
  rescue
121
    # can probably get here for a couple reasons
122
    #  1)  maybe: dir deleted between time entries called and delete called
123
    #  2)  maybe: if dir name contains non-ascii chars: Ruby may choke with Errno::ENOENT
124
    #  maybe more
125
    # do nothing so we can continue with other files
126
  end
127
end
128

    
129
def trimDirectory(dirPath,directory)
130
  
131
  relDirName = dirPath + "\\" + directory
132
  copyFullDirName = COPY_DRIVE + relDirName
133
  if copyFullDirName.length > 255
134
    $logFile.print "***Directory path too long in trimDirectory: #{copyFullDirName}\n"
135
    return
136
  end
137
  Dir.foreach(copyFullDirName) do | dirEntry |
138
    next if (dirEntry == ".") or (dirEntry == "..")
139
    if (copyFullDirName.length + 1 + dirEntry.length) > 255
140
      $logFile.print "***File path too long in trimDirectory: #{copyFullDirName+"\\"+dirEntry}\n"
141
    elsif File.directory?(copyFullDirName+"\\"+dirEntry)
142
      trimDirectory(relDirName,dirEntry)
143
      deleteDirectoryIfNecessary(relDirName,dirEntry)
144
    else  # its a file
145
      deleteFileIfNecessary(relDirName,dirEntry)
146
    end
147
  end
148
    
149
end
150
  
151
def trimMachine
152
  trimDirectory("",".")
153
end
154

    
155
def setupAndTrimMachine(usr,psswd,src,dest)
156
  
157
  $logFile.print "\n\n*******Start TRIMMING machine: #{src}\n\n"
158
  print "\n\n*******Start TRIMMING machine: #{src}\n\n"
159
  
160
  # make sure the two drives are not allocated
161
  system("net use #{COPY_DRIVE} /delete")
162
  system("net use #{ORIG_DRIVE} /delete")
163
  
164
  # map source drive: \\machine\drive psswd /user:usr
165
  $logFile.print "Mapping ORIG_DRIVE (#{ORIG_DRIVE}) to #{src}\n"
166
  print "Mapping ORIG_DRIVE (#{ORIG_DRIVE}) to #{src}\n"
167
  system("net use #{ORIG_DRIVE} #{src} #{psswd} /user:#{usr}")
168

    
169
  # map dest drive: \\server\share\machine\drive
170
  $logFile.print "Mapping COPY_DRIVE (#{COPY_DRIVE}) to #{dest}\n"
171
  print "Mapping COPY_DRIVE (#{COPY_DRIVE}) to #{dest}\n"
172
  system("net use #{COPY_DRIVE} #{dest}")
173

    
174
  trimMachine
175

    
176
  # deallocate the two drives
177
  system("net use #{COPY_DRIVE} /delete")
178
  system("net use #{ORIG_DRIVE} /delete")
179
  
180
  $logFile.print "\n\n*******End   TRIMMING machine: #{src}\n\n"
181
  print "\n\n*******End   TRIMMING machine: #{src}\n\n"
182
  
183
end
184

    
185
def trimMachines(server,share)
186

    
187
  Dir.foreach("\\\\#{server}\\#{share}") do | machine |
188
    
189
    next if machine == "."
190
    next if machine == ".."
191
    
192
    # do nothing if machine not available to network
193
    next if not machineReady(machine)
194
    
195
    creds = $credentials[machine]
196
    
197
    # do nothing if this machine is no longer referenced in backup data file
198
    next if creds.nil?
199
    
200
    Dir.foreach("\\\\#{server}\\#{share}\\#{machine}") do | drive |
201

    
202
      next if drive == "."
203
      next if drive == ".."
204
      
205
      srcDir = "\"\\\\#{machine}\\#{drive}\""
206
      dstDir = "\"\\\\#{server}\\#{share}\\#{machine}\\#{drive}\""
207
      
208
      setupAndTrimMachine(creds[0], decrypt(creds[1]), srcDir, dstDir)
209
        
210
    end
211
    
212
  end
213
  
214
end
215

    
216
def next8pm(now)
217
  retTime = Time.local(now.year,now.month,now.day,20,0,0)
218
  if now.hour >= 20 # its between 8 pm and midnight
219
    retTime = retTime + SecondsPerDay  # add a day's worth of seconds
220
  end
221
  retTime
222
end
223

    
224
def saveOldLogs
225
  8.downto(1) do | logNum |
226
    logFile = "trim0#{logNum}.log"
227
    if FileTest.exist?(logFile)
228
      savedFile = "trim0#{logNum+1}.log"
229
      File.rm_f(savedFile) if FileTest.exist?(savedFile)
230
      # file move from curr log to next log
231
      File.move(logFile,savedFile)
232
    end
233
  end
234
  logFile = "trim01.log"
235
  File.rm_f(logFile) if FileTest.exist?(logFile)
236
end
237

    
238
until true == false
239
  
240
  if not DEBUGGING
241
    #sleep until the next 8 pm
242
    now = Time.now
243
    secondsToSleep = next8pm(now) - now
244
    print "\n\n ********* Sleeping #{secondsToSleep} seconds until 8:00 pm ********* \n\n"
245
    sleep(secondsToSleep)
246
  end
247

    
248
  saveOldLogs
249
  $logFile = File.open("trim01.log","w")
250
  
251
  loadCredentials
252
  
253
  trimMachines("Ironman","dept1")
254
  trimMachines("Ironman","dept2")
255
  trimMachines("Ironman","it")
256
  trimMachines("Ironman","office")
257
  
258
  $logFile.close
259
end