configurationengine/source/cone/storage/zipstorage.py
changeset 5 d2c80f5cab53
parent 3 e7e0ae78773e
equal deleted inserted replaced
4:0951727b8815 5:d2c80f5cab53
    53         """
    53         """
    54         self.mode        = mode
    54         self.mode        = mode
    55         self.persistentmodule = persistentconfml
    55         self.persistentmodule = persistentconfml
    56         self.compression = zipfile.ZIP_DEFLATED
    56         self.compression = zipfile.ZIP_DEFLATED
    57         self.modified = False
    57         self.modified = False
       
    58         self.cache = {}
    58         self.logger = logging.getLogger('cone')
    59         self.logger = logging.getLogger('cone')
    59         self.logger.debug("ZipStorage path %s open in mode %s" % (path,self.mode))
    60         self.logger.debug("ZipStorage path %s open in mode %s" % (path,self.mode))
    60         try:
    61         try:
    61             # If opening the file in read/append mode check that the given file is a zipfile
    62             # If opening the file in read/append mode check that the given file is a zipfile
    62             if self.get_mode(mode) != self.MODE_WRITE:
    63             if self.get_mode(mode) != self.MODE_WRITE:
   282         if self.zipfile:
   283         if self.zipfile:
   283             super(ZipStorage,self).close()
   284             super(ZipStorage,self).close()
   284             self.zipfile.close()
   285             self.zipfile.close()
   285             # Recreate the zip file if the zip has been modified to make a zip without 
   286             # Recreate the zip file if the zip has been modified to make a zip without 
   286             # duplicate local file entries
   287             # duplicate local file entries
   287             if self.modified:
   288         else:
   288                 oldfile = None
   289             raise exceptions.StorageException('Storage %s has been already closed!' % self.path)
   289                 newzipfile = None
   290 
   290                 fh, tmp_path = tempfile.mkstemp(suffix='.zip')
   291         if self.modified or self.cache:
   291                 shutil.move(self.path, tmp_path)
   292             logging.getLogger('cone').debug("Recreating the ZIP output file")
   292                 oldfile = zipfile.ZipFile(tmp_path,"r")
   293             oldfile = None
   293                 newzipfile = zipfile.ZipFile(self.path,"w",self.compression)
   294             newzipfile = None
   294                 for fileinfo in oldfile.infolist():
   295             fh, tmp_path = tempfile.mkstemp(suffix='.zip')
       
   296             shutil.move(self.path, tmp_path)
       
   297             oldfile = zipfile.ZipFile(tmp_path,"r")
       
   298             newzipfile = zipfile.ZipFile(self.path,"w",self.compression)
       
   299             for fileinfo in oldfile.infolist():
       
   300                 if fileinfo.filename not in self.cache.keys():
   295                     newzipfile.writestr(fileinfo, oldfile.read(fileinfo.filename))
   301                     newzipfile.writestr(fileinfo, oldfile.read(fileinfo.filename))
   296                 if oldfile: oldfile.close()
   302             for filename in sorted(self.cache.keys()):
   297                 if newzipfile: newzipfile.close()
   303                 logging.getLogger('cone').debug("Adding pre-cached file %s." % filename)
   298                 os.close(fh)
   304                 newzipfile.write(self.cache[filename], arcname=filename)
   299                 os.unlink(tmp_path)
   305             if oldfile: oldfile.close()
   300             self.zipfile = None
   306             if newzipfile: newzipfile.close()
   301         else:
   307             os.close(fh)
   302             raise exceptions.StorageException('Storage %s has been already closed!' % self.path)
   308             os.unlink(tmp_path)
       
   309             logging.getLogger('cone').debug("Recreating the ZIP output file completed.")
       
   310         
       
   311         self.zipfile = None
   303 
   312 
   304     def unload(self, path, object):
   313     def unload(self, path, object):
   305         """
   314         """
   306         Dump a given object to the storage (reference is fetched from the object)
   315         Dump a given object to the storage (reference is fetched from the object)
   307         @param object: The object to dump to the storage, which is expected to be an instance 
   316         @param object: The object to dump to the storage, which is expected to be an instance