Trees | Indices | Help |
|
---|
|
1 #!/usr/bin/python 2 3 # Rekall 4 # Copyright 2014 Google Inc. All Rights Reserved. 5 # 6 # This program is free software; you can redistribute it and/or modify 7 # it under the terms of the GNU General Public License as published by 8 # the Free Software Foundation; either version 2 of the License, or (at 9 # your option) any later version. 10 # 11 # This program is distributed in the hope that it will be useful, but 12 # WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # You should have received a copy of the GNU General Public License 17 # along with this program; if not, write to the Free Software 18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 # 20 21 """This file implements a caching URL manager. 22 23 We locally cache selected files from the remote profile repository. If a profile 24 is not found in the local cache, we retrieve it from the remote repository, and 25 add it to the cache. 26 27 We check the remote repository for staleness and update the local cache in the 28 background. 29 """ 30 31 __author__ = "Michael Cohen <scudette@google.com>" 32 from rekall import cache 33 from rekall import config 34 from rekall import io_manager 35 36 37 config.DeclareOption( 38 "cache_dir", default=None, 39 help="Location of the profile cache directory.") 40 4143 44 # We wrap this io manager class 45 DELEGATE = io_manager.URLManager 46 47 # If the cache is available we should be selected before the regular 48 # manager. 49 order = DELEGATE.order - 10 50139 140 14352 super(CachingManager, self).__init__(session=session, **kwargs) 53 54 cache_dir = cache.GetCacheDir(session) 55 56 # We use an IO manager to manage the cache directory directly. 57 self.cache_io_manager = io_manager.DirectoryIOManager(urn=cache_dir, 58 session=session) 59 self.url_manager = self.DELEGATE(session=session, **kwargs) 60 61 self.CheckUpstreamRepository()62 6567 """Do we have this file at all? 68 69 Search for it in either the cache or in the delegate. 70 """ 71 if self.cache_io_manager.CheckInventory(name): 72 return True 73 74 return self.url_manager.CheckInventory(name)7577 if self.cache_io_manager.CheckInventory(name): 78 local_age = self.cache_io_manager.Metadata(name).get( 79 "LastModified", 0) 80 remote_age = self.url_manager.Metadata(name).get("LastModified") 81 if remote_age is None: 82 # The remote might not have this file at all, in case we 83 # downloaded it locally (e.g. with build_local_profile). 84 self.session.logging.debug("Remote does not have file %s.", name) 85 remote_age = 0 86 87 # Only get the local copy if it is not older than the remote 88 # copy. This allows the remote end to update profiles and we will 89 # automatically pick the latest. 90 if local_age >= remote_age: 91 data = self.cache_io_manager.GetData(name) 92 # Ensure our local cache looks reasonable. 93 if data.get("$METADATA"): 94 return data 95 96 # Fetch the data from our base class and store it in the cache. 97 data = self.url_manager.GetData(name, **kwargs) 98 99 # Only store the data in the cache if it looks reasonable. Otherwise we 100 # will trash the cache with bad data in case we can not access correct 101 # data. 102 if data and data.get("$METADATA"): 103 self.session.logging.debug("Adding %s to local cache.", name) 104 self.cache_io_manager.StoreData(name, data) 105 106 return data107 110112 """Checks the repository for freshness.""" 113 upstream_inventory = self.url_manager.inventory 114 115 # This indicates failure to contact the remote repository. In this case 116 # we do not want to invalidate our cache, just use the cache as is. 117 if not self.url_manager.ValidateInventory(): 118 self.session.logging.warn( 119 "Repository %s will be disabled.", self.urn) 120 raise ValueError("Invalid inventory.") 121 122 cache_inventory = self.cache_io_manager.inventory 123 modified = False 124 125 for item, metadata in cache_inventory.get("$INVENTORY", {}).items(): 126 upstream_meta = upstream_inventory.get( 127 "$INVENTORY", {}).get(item) 128 129 if (upstream_meta is None or 130 upstream_meta["LastModified"] > metadata["LastModified"]): 131 cache_inventory["$INVENTORY"].pop(item) 132 modified = True 133 134 if modified: 135 self.cache_io_manager.FlushInventory()136138 return self.url_manager.ListFiles()
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Oct 9 03:29:38 2017 | http://epydoc.sourceforge.net |