1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23   
 24   
 25   
 26   
 27   
 28   
 29   
 30   
 31   
 32   
 33   
 34   
 35   
 36   
 37   
 38  """ 
 39  Implements the standard 'validate' action. 
 40  @sort: executeValidate 
 41  @author: Kenneth J. Pronovici <pronovic@ieee.org> 
 42  """ 
 43   
 44   
 45   
 46   
 47   
 48   
 49   
 50  import os 
 51  import logging 
 52   
 53   
 54  from CedarBackup2.util import getUidGid, getFunctionReference 
 55  from CedarBackup2.actions.util import createWriter 
 56   
 57   
 58   
 59   
 60   
 61   
 62  logger = logging.getLogger("CedarBackup2.log.actions.validate") 
 63   
 64   
 65   
 66   
 67   
 68   
 69   
 70   
 71   
 72   
 73   
 75     """ 
 76     Executes the validate action. 
 77   
 78     This action validates each of the individual sections in the config file. 
 79     This is a "runtime" validation.  The config file itself is already valid in 
 80     a structural sense, so what we check here that is that we can actually use 
 81     the configuration without any problems. 
 82   
 83     There's a separate validation function for each of the configuration 
 84     sections.  Each validation function returns a true/false indication for 
 85     whether configuration was valid, and then logs any configuration problems it 
 86     finds.  This way, one pass over configuration indicates most or all of the 
 87     obvious problems, rather than finding just one problem at a time. 
 88   
 89     Any reported problems will be logged at the ERROR level normally, or at the 
 90     INFO level if the quiet flag is enabled. 
 91   
 92     @param configPath: Path to configuration file on disk. 
 93     @type configPath: String representing a path on disk. 
 94   
 95     @param options: Program command-line options. 
 96     @type options: Options object. 
 97   
 98     @param config: Program configuration. 
 99     @type config: Config object. 
100   
101     @raise ValueError: If some configuration value is invalid. 
102     """ 
103     logger.debug("Executing the 'validate' action.") 
104     if options.quiet: 
105        logfunc = logger.info    
106     else: 
107        logfunc = logger.error   
108     valid = True 
109     valid &= _validateReference(config, logfunc) 
110     valid &= _validateOptions(config, logfunc) 
111     valid &= _validateCollect(config, logfunc) 
112     valid &= _validateStage(config, logfunc) 
113     valid &= _validateStore(config, logfunc) 
114     valid &= _validatePurge(config, logfunc) 
115     valid &= _validateExtensions(config, logfunc) 
116     if valid: 
117        logfunc("Configuration is valid.") 
118     else: 
119        logfunc("Configuration is not valid.") 
 120   
121   
122   
123   
124   
125   
126   
127   
128   
129   
130 -def _checkDir(path, writable, logfunc, prefix): 
 131     """ 
132     Checks that the indicated directory is OK. 
133   
134     The path must exist, must be a directory, must be readable and executable, 
135     and must optionally be writable. 
136   
137     @param path: Path to check. 
138     @param writable: Check that path is writable. 
139     @param logfunc: Function to use for logging errors. 
140     @param prefix: Prefix to use on logged errors. 
141   
142     @return: True if the directory is OK, False otherwise. 
143     """ 
144     if not os.path.exists(path): 
145        logfunc("%s [%s] does not exist." % (prefix, path)) 
146        return False 
147     if not os.path.isdir(path): 
148        logfunc("%s [%s] is not a directory." % (prefix, path)) 
149        return False 
150     if not os.access(path, os.R_OK): 
151        logfunc("%s [%s] is not readable." % (prefix, path)) 
152        return False 
153     if not os.access(path, os.X_OK): 
154        logfunc("%s [%s] is not executable." % (prefix, path)) 
155        return False 
156     if writable and not os.access(path, os.W_OK): 
157        logfunc("%s [%s] is not writable." % (prefix, path)) 
158        return False 
159     return True 
 160   
161   
162   
163   
164   
165   
167     """ 
168     Execute runtime validations on reference configuration. 
169   
170     We only validate that reference configuration exists at all. 
171   
172     @param config: Program configuration. 
173     @param logfunc: Function to use for logging errors 
174   
175     @return: True if configuration is valid, false otherwise. 
176     """ 
177     valid = True 
178     if config.reference is None: 
179        logfunc("Required reference configuration does not exist.") 
180        valid = False 
181     return valid 
 182   
183   
184   
185   
186   
187   
189     """ 
190     Execute runtime validations on options configuration. 
191   
192     The following validations are enforced: 
193   
194        - The options section must exist 
195        - The working directory must exist and must be writable 
196        - The backup user and backup group must exist 
197   
198     @param config: Program configuration. 
199     @param logfunc: Function to use for logging errors 
200   
201     @return: True if configuration is valid, false otherwise. 
202     """ 
203     valid = True 
204     if config.options is None: 
205        logfunc("Required options configuration does not exist.") 
206        valid = False 
207     else: 
208        valid &= _checkDir(config.options.workingDir, True, logfunc, "Working directory") 
209        try: 
210           getUidGid(config.options.backupUser, config.options.backupGroup) 
211        except ValueError: 
212           logfunc("Backup user:group [%s:%s] invalid." % (config.options.backupUser, config.options.backupGroup)) 
213           valid = False 
214     return valid 
 215   
216   
217   
218   
219   
220   
222     """ 
223     Execute runtime validations on collect configuration. 
224   
225     The following validations are enforced: 
226   
227        - The target directory must exist and must be writable 
228        - Each of the individual collect directories must exist and must be readable 
229   
230     @param config: Program configuration. 
231     @param logfunc: Function to use for logging errors 
232   
233     @return: True if configuration is valid, false otherwise. 
234     """ 
235     valid = True 
236     if config.collect is not None: 
237        valid &= _checkDir(config.collect.targetDir, True, logfunc, "Collect target directory") 
238        if config.collect.collectDirs is not None: 
239           for collectDir in config.collect.collectDirs: 
240              valid &= _checkDir(collectDir.absolutePath, False, logfunc, "Collect directory") 
241     return valid 
 242   
243   
244   
245   
246   
247   
249     """ 
250     Execute runtime validations on stage configuration. 
251   
252     The following validations are enforced: 
253   
254        - The target directory must exist and must be writable 
255        - Each local peer's collect directory must exist and must be readable 
256   
257     @note: We currently do not validate anything having to do with remote peers, 
258     since we don't have a straightforward way of doing it.  It would require 
259     adding an rsh command rather than just an rcp command to configuration, and 
260     that just doesn't seem worth it right now. 
261   
262     @param config: Program configuration. 
263     @param logfunc: Function to use for logging errors 
264   
265     @return: True if configuration is valid, False otherwise. 
266     """ 
267     valid = True 
268     if config.stage is not None: 
269        valid &= _checkDir(config.stage.targetDir, True, logfunc, "Stage target dir ") 
270        if config.stage.localPeers is not None: 
271           for peer in config.stage.localPeers: 
272              valid &= _checkDir(peer.collectDir, False, logfunc, "Local peer collect dir ") 
273     return valid 
 274   
275   
276   
277   
278   
279   
281     """ 
282     Execute runtime validations on store configuration. 
283   
284     The following validations are enforced: 
285   
286        - The source directory must exist and must be readable 
287        - The backup device (path and SCSI device) must be valid 
288   
289     @param config: Program configuration. 
290     @param logfunc: Function to use for logging errors 
291   
292     @return: True if configuration is valid, False otherwise. 
293     """ 
294     valid = True 
295     if config.store is not None: 
296        valid &= _checkDir(config.store.sourceDir, False, logfunc, "Store source directory") 
297        try: 
298           createWriter(config) 
299        except ValueError: 
300           logfunc("Backup device [%s] [%s] is not valid." % (config.store.devicePath, config.store.deviceScsiId)) 
301           valid = False 
302     return valid 
 303   
304   
305   
306   
307   
308   
310     """ 
311     Execute runtime validations on purge configuration. 
312   
313     The following validations are enforced: 
314   
315        - Each purge directory must exist and must be writable 
316   
317     @param config: Program configuration. 
318     @param logfunc: Function to use for logging errors 
319   
320     @return: True if configuration is valid, False otherwise. 
321     """ 
322     valid = True 
323     if config.purge is not None: 
324        if config.purge.purgeDirs is not None: 
325           for purgeDir in config.purge.purgeDirs: 
326              valid &= _checkDir(purgeDir.absolutePath, True, logfunc, "Purge directory") 
327     return valid 
 328   
329   
330   
331   
332   
333   
360