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 'rebuild' action. 
 40  @sort: executeRebuild 
 41  @author: Kenneth J. Pronovici <pronovic@ieee.org> 
 42  """ 
 43   
 44   
 45   
 46   
 47   
 48   
 49   
 50  import sys 
 51  import os 
 52  import logging 
 53  import datetime 
 54   
 55   
 56  from CedarBackup2.util import deriveDayOfWeek 
 57  from CedarBackup2.actions.util import checkMediaState 
 58  from CedarBackup2.actions.constants import DIR_TIME_FORMAT, STAGE_INDICATOR 
 59  from CedarBackup2.actions.store import writeImage, writeStoreIndicator, consistencyCheck 
 60   
 61   
 62   
 63   
 64   
 65   
 66  logger = logging.getLogger("CedarBackup2.log.actions.rebuild") 
 67   
 68   
 69   
 70   
 71   
 72   
 73   
 74   
 75   
 76   
 77   
 79     """ 
 80     Executes the rebuild backup action. 
 81   
 82     This function exists mainly to recreate a disc that has been "trashed" due 
 83     to media or hardware problems.  Note that the "stage complete" indicator 
 84     isn't checked for this action. 
 85   
 86     Note that the rebuild action and the store action are very similar.  The 
 87     main difference is that while store only stores a single day's staging 
 88     directory, the rebuild action operates on multiple staging directories. 
 89   
 90     @param configPath: Path to configuration file on disk. 
 91     @type configPath: String representing a path on disk. 
 92   
 93     @param options: Program command-line options. 
 94     @type options: Options object. 
 95   
 96     @param config: Program configuration. 
 97     @type config: Config object. 
 98   
 99     @raise ValueError: Under many generic error conditions 
100     @raise IOError: If there are problems reading or writing files. 
101     """ 
102     logger.debug("Executing the 'rebuild' action.") 
103     if sys.platform == "darwin": 
104        logger.warn("Warning: the rebuild action is not fully supported on Mac OS X.") 
105        logger.warn("See the Cedar Backup software manual for further information.") 
106     if config.options is None or config.store is None: 
107        raise ValueError("Rebuild configuration is not properly filled in.") 
108     if config.store.checkMedia: 
109        checkMediaState(config.store)   
110     stagingDirs = _findRebuildDirs(config) 
111     writeImage(config, True, stagingDirs) 
112     if config.store.checkData: 
113        if sys.platform == "darwin": 
114           logger.warn("Warning: consistency check cannot be run successfully on Mac OS X.") 
115           logger.warn("See the Cedar Backup software manual for further information.") 
116        else: 
117           logger.debug("Running consistency check of media.") 
118           consistencyCheck(config, stagingDirs) 
119     writeStoreIndicator(config, stagingDirs) 
120     logger.info("Executed the 'rebuild' action successfully.") 
 121   
122   
123   
124   
125   
126   
127   
128   
129   
130   
132     """ 
133     Finds the set of directories to be included in a disc rebuild. 
134   
135     A the rebuild action is supposed to recreate the "last week's" disc.  This 
136     won't always be possible if some of the staging directories are missing. 
137     However, the general procedure is to look back into the past no further than 
138     the previous "starting day of week", and then work forward from there trying 
139     to find all of the staging directories between then and now that still exist 
140     and have a stage indicator. 
141   
142     @param config: Config object. 
143   
144     @return: Correct staging dir, as a dict mapping directory to date suffix. 
145     @raise IOError: If we do not find at least one staging directory. 
146     """ 
147     stagingDirs = {} 
148     start = deriveDayOfWeek(config.options.startingDay) 
149     today = datetime.date.today() 
150     if today.weekday() >= start: 
151        days = today.weekday() - start + 1 
152     else: 
153        days = 7 - (start - today.weekday()) + 1 
154     for i in range (0, days): 
155        currentDay = today - datetime.timedelta(days=i) 
156        dateSuffix = currentDay.strftime(DIR_TIME_FORMAT) 
157        stageDir = os.path.join(config.store.sourceDir, dateSuffix) 
158        indicator = os.path.join(stageDir, STAGE_INDICATOR) 
159        if os.path.isdir(stageDir) and os.path.exists(indicator): 
160           logger.info("Rebuild process will include stage directory [%s]", stageDir) 
161           stagingDirs[stageDir] = dateSuffix 
162     if len(stagingDirs) == 0: 
163        raise IOError("Unable to find any staging directories for rebuild process.") 
164     return stagingDirs 
 165