~hdlorean-db/hdlorean/db

« back to all changes in this revision

Viewing changes to src/hdloreand/snapshotManager/RdiffBackupWrapper.py

  • Committer: Winterfuse
  • Date: 2008-04-05 18:15:03 UTC
  • mfrom: (49.37.3 db)
  • Revision ID: adrianbn@gmail.com-20080405181503-bn68mbaepy0brlvy
Merged with db

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: UTF-8 -*-
2
 
 
3
 
import os
4
 
import os.path
5
 
import sys
6
 
import string
7
 
import shutil
8
 
from popen2 import Popen3
9
 
from IStorageWrapper import IStorageWrapper
10
 
 
11
 
## Wraps rdiff-backup application.
12
 
#
13
 
# @author Salvador de la Puente González
14
 
# @contact neo.salvador@gmail.com
15
 
class RdiffBackupWrapper(IStorageWrapper):      
16
 
        ## rdiff-backup command
17
 
        #
18
 
        __rdiffCommand = "rdiff-backup"
19
 
        
20
 
        ## rdiff-backup command prototype to check backup directory
21
 
        #
22
 
        __cmdCheckBackupDirectory = __rdiffCommand + " --check-destination-dir \"$snapshotPath$\""
23
 
        
24
 
        ## rdiff-backup command prototype to setup backup directory
25
 
        #
26
 
        __cmdSetupBackupDirectory = __rdiffCommand + " --create-full-path --exclude-regexp '.' / \"$snapshotPath$\""
27
 
        
28
 
        ## rdiff-backup command prototype to backup a new file or directory
29
 
        #
30
 
        __cmdBackupNewPath = __rdiffCommand + " $pathsIncluded$ --exclude-regexp '.' / \"$snapshotPath$\""
31
 
        
32
 
        ## rdiff-backup command prototype to recover a snapshot
33
 
        #
34
 
        __cmdRecoverAtTime = __rdiffCommand + " -r '$time$' --force \"$snapshotPath$\" \"$targetPath$\"" 
35
 
        
36
 
        ## rdiff-backup command prototype to recover a given path at given time to given target path
37
 
        #
38
 
        __cmdRecoverPathAtTime = __rdiffCommand + " -r '$time$' --force --include \"$sourcePath$\" --exclude-regexp '.' \"$snapshotPath$\" \"$targetPath$\""
39
 
        
40
 
        ## rdiff-backup command prototype to list all snapshots performed
41
 
        #
42
 
        __cmdListSnapshots = __rdiffCommand + " -l \"$snapshotPath$\""
43
 
        
44
 
        ## rdiff-backup command prototype to list content from a directory at given time
45
 
        #
46
 
        __cmdListAtTime = __rdiffCommand + " --list-at-time '$time$' \"$snapshotPath$$dirPath$\""
47
 
        
48
 
        ## rdiff-backup command prototype to list content from a directory at given time
49
 
        # TODO: falta este, va a dar problemas porque es una opción inexistente en rdiff-backup
50
 
        
51
 
        ## Default constructor setups object properly
52
 
        #
53
 
        def __init__(self):
54
 
                # FIXME: preguntar a config manager
55
 
                snapshotDirectory = os.path.normpath(os.getenv("HOME") + "/.hdlorean/snapshots")
56
 
                self._IStorageWrapper__snapshotsDirectory = snapshotDirectory
57
 
                
58
 
                # Setup cmd private attributes
59
 
                self.__cmdCheckBackupDirectory = string.replace(self.__cmdCheckBackupDirectory, "$snapshotPath$", snapshotDirectory)
60
 
                self.__cmdSetupBackupDirectory = string.replace(self.__cmdSetupBackupDirectory, "$snapshotPath$", snapshotDirectory)
61
 
                self.__cmdBackupNewPath = string.replace(self.__cmdBackupNewPath, "$snapshotPath$", snapshotDirectory)
62
 
                self.__cmdRecoverAtTime = string.replace(self.__cmdRecoverAtTime, "$snapshotPath$", snapshotDirectory)
63
 
                self.__cmdRecoverPathAtTime = string.replace(self.__cmdRecoverPathAtTime, "$snapshotPath$", snapshotDirectory)
64
 
                self.__cmdListAtTime = string.replace(self.__cmdListAtTime, "$snapshotPath$", snapshotDirectory)
65
 
                self.__cmdListSnapshots = string.replace(self.__cmdListSnapshots, "$snapshotPath$", snapshotDirectory)
66
 
                
67
 
                # FIXME: Mejorar el sistema de comprobación, quizá pedir externamente
68
 
                command = self.__cmdCheckBackupDirectory 
69
 
                print >> sys.stderr, "EXEC>" + command
70
 
                result = Popen3(command)
71
 
                status = result.wait()
72
 
                status = status >> 8            
73
 
                if status != 0 :
74
 
                        command = self.__cmdSetupBackupDirectory
75
 
                        print >> sys.stderr, "EXEC>" + command
76
 
                        result = Popen3(command)
77
 
                        status = result.wait()
78
 
                        status = status >> 8
79
 
                        # TODO: Añadir control de errores
80
 
                        print >> sys.stderr, "Backup directory was created succesfully"
81
 
                else:
82
 
                        print >> sys.stderr, "Backup directory already exists"
83
 
                        
84
 
                # REMEMBER: rdiff-backup tiene una resolución máxima de segundos
85
 
                os.popen("sleep 1");
86
 
                
87
 
        
88
 
        ## Backups a set of files
89
 
        #
90
 
        # @param setFileSet a set with absolute paths to files to be backupped
91
 
        def backupSet(self, setFileSet):
92
 
                pathsIncluded = ""
93
 
                for filePath in setFileSet:
94
 
                        pathsIncluded = pathsIncluded + " --include \"" + filePath + "\""
95
 
                
96
 
                command = string.replace(self.__cmdBackupNewPath, "$pathsIncluded$", pathsIncluded)
97
 
                print >> sys.stderr, "EXEC>" + command
98
 
                result = Popen3(command)
99
 
                status = result.wait()
100
 
                status = status >> 8
101
 
                # TODO: Añadir control de errores y devolver el log
102
 
                
103
 
                # REMEMBER: rdiff-backup tiene una resolución máxima de segundos
104
 
                os.popen("sleep 1");
105
 
                return True
106
 
          
107
 
        ## Recovers a snapshot at given time to a given target directory
108
 
        #
109
 
        # @param strTime time of the backup to be recovered
110
 
        # @param strTargetPath target directory to copy recovered snapshot
111
 
        def recoverSnapshotAtTime(self, strTime, strTargetPath):
112
 
                # Make target path if it does not exist
113
 
                if(not os.path.exists(strTargetPath)):
114
 
                        os.makedirs(strTargetPath)
115
 
                
116
 
                command = string.replace(self.__cmdRecoverAtTime, "$time$", strTime)
117
 
                command = string.replace(command, "$targetPath$", strTargetPath)
118
 
                print >> sys.stderr, "EXEC>" + command
119
 
                result = Popen3(command)
120
 
                status = result.wait()
121
 
                status = status >> 8
122
 
                # TODO: Añadir control de errores y devolver el log
123
 
                
124
 
        
125
 
        ## Recovers a given path at given time to a given target directory
126
 
        #
127
 
        # @param strSourcePath path to recover
128
 
        # @param strTime time of the snapshot to be recovered
129
 
        # @param strTargetPath target directory to copy recovered snapshot
130
 
        def recoverPathAtTime(self, strSourcePath, strTime, strTargetPath):
131
 
                # Temporal path
132
 
                strTmpPath = "/tmp/hdlorean/"
133
 
                
134
 
                if(not os.path.exists(strTmpPath)):
135
 
                        os.makedirs(strTmpPath)
136
 
                
137
 
                # Make target path if it does not exist
138
 
                if(not os.path.exists(strTargetPath)):
139
 
                        os.makedirs(strTargetPath)
140
 
                        
141
 
                # During restoration, rdiff-backup, overwrite permissions and automatically fix the type of the path. Its an util trick.
142
 
                fixedSource = os.path.normpath(strTmpPath + "/" + strSourcePath)
143
 
                if(not os.path.exists(fixedSource)):
144
 
                        os.makedirs(fixedSource)                
145
 
                
146
 
                command = string.replace(self.__cmdRecoverPathAtTime, "$sourcePath$", fixedSource)
147
 
                command = string.replace(command, "$time$", strTime)
148
 
                command = string.replace(command, "$targetPath$", strTmpPath)
149
 
                print >> sys.stderr, "EXEC>" + command
150
 
                result = Popen3(command)
151
 
                status = result.wait()
152
 
                status = status >> 8
153
 
                # TODO: Añadir control de errores y devolver el log
154
 
                
155
 
                # Move files to target path
156
 
                shutil.move(fixedSource, strTargetPath)
157
 
                
158
 
                # Remove temp files
159
 
                shutil.rmtree(strTmpPath, True)
160
 
                        
161
 
        
162
 
        ## Deletes an specified snapshot at given time
163
 
        #
164
 
        # @param strTime time of the snapshot to be deleted
165
 
        def deleteAtTime(self, strTime):
166
 
                # TODO: Diseñar el comando apañando convenientemente el contenido de la carpeta de backups de rdiff
167
 
                raise "Not implemented yet"
168
 
        
169
 
        ## Gets a list of the content of the given directory at given time
170
 
        #
171
 
        # @param strDir directory path to list it content
172
 
        # @param strTime specify when list operation is performed
173
 
        # @param boolRecursive if true, then it returns the content of folder and its subfolders. Otherwise, just returns content of folder
174
 
        # @return an array with the content of the folder and some important metadata
175
 
        def getDirList(self, strDir, strTime, boolRecursive):
176
 
                command = string.replace(self.__cmdListAtTime, "$time$", strTime)
177
 
                command = string.replace(command, "$dirPath$", strDir)
178
 
                print >> sys.stderr, "EXEC>" + command
179
 
                result = Popen3(command)
180
 
                status = result.wait()
181
 
                content = result.fromchild.readlines()
182
 
                filteredContent = []
183
 
                
184
 
                # Filter content if recursive option is disabled
185
 
                # TODO: Añadir metadata de interés como son los permisos, tamaño...
186
 
                if not boolRecursive:
187
 
                        for filePath in content:
188
 
                                head, tail = os.path.split(filePath)
189
 
                                head = "/" + head
190
 
                                # REMEMBER: Cuando rdiff lista, no mete la barra inicial, hay que añadirla, para asegurarnos, comparamos después de normalizar
191
 
                                if os.path.normpath(head) == os.path.normpath(strDir):
192
 
                                        filteredContent = filteredContent + [filePath]
193
 
                else:
194
 
                        filteredContent = content
195
 
                        
196
 
                status = status >> 8
197
 
                # TODO: Añadir control de errores
198
 
                
199
 
                return filteredContent
200
 
        
201
 
        ## Gets a list of all snapshot performed by now
202
 
        #
203
 
        # @return an array with all snapshots available
204
 
        def getAllSnapshots(self):
205
 
                command = self.__cmdListSnapshots
206
 
                print >> sys.stderr, "EXEC>" + command
207
 
                result = Popen3(command)
208
 
                status = result.wait()
209
 
                snapshots = result.fromchild.readlines()
210
 
                # TODO: traducir a un mejor formato
211
 
                status = status >> 8
212
 
                # TODO: Añadir control de errores
213
 
                
214
 
                return snapshots