Package ganeti :: Package storage :: Module filestorage
[hide private]
[frames] | no frames]

Source Code for Module ganeti.storage.filestorage

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2013 Google Inc. 
  5  # All rights reserved. 
  6  # 
  7  # Redistribution and use in source and binary forms, with or without 
  8  # modification, are permitted provided that the following conditions are 
  9  # met: 
 10  # 
 11  # 1. Redistributions of source code must retain the above copyright notice, 
 12  # this list of conditions and the following disclaimer. 
 13  # 
 14  # 2. Redistributions in binary form must reproduce the above copyright 
 15  # notice, this list of conditions and the following disclaimer in the 
 16  # documentation and/or other materials provided with the distribution. 
 17  # 
 18  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
 19  # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
 20  # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 21  # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 22  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 23  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 24  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 25  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 26  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 27  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 28  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 29   
 30   
 31  """File storage functions. 
 32   
 33  """ 
 34   
 35  import logging 
 36  import os 
 37   
 38  from ganeti import compat 
 39  from ganeti import constants 
 40  from ganeti import errors 
 41  from ganeti import pathutils 
 42  from ganeti import utils 
 43   
 44   
45 -def GetFileStorageSpaceInfo(path):
46 """Retrieves the free and total space of the device where the file is 47 located. 48 49 @type path: string 50 @param path: Path of the file whose embracing device's capacity is 51 reported. 52 @return: a dictionary containing 'vg_size' and 'vg_free' given in MebiBytes 53 54 """ 55 try: 56 result = os.statvfs(path) 57 free = (result.f_frsize * result.f_bavail) / (1024 * 1024) 58 size = (result.f_frsize * result.f_blocks) / (1024 * 1024) 59 return {"type": constants.ST_FILE, 60 "name": path, 61 "storage_size": size, 62 "storage_free": free} 63 except OSError, e: 64 raise errors.CommandError("Failed to retrieve file system information about" 65 " path: %s - %s" % (path, e.strerror))
66 67
68 -def _GetForbiddenFileStoragePaths():
69 """Builds a list of path prefixes which shouldn't be used for file storage. 70 71 @rtype: frozenset 72 73 """ 74 paths = set([ 75 "/boot", 76 "/dev", 77 "/etc", 78 "/home", 79 "/proc", 80 "/root", 81 "/sys", 82 ]) 83 84 for prefix in ["", "/usr", "/usr/local"]: 85 paths.update(map(lambda s: "%s/%s" % (prefix, s), 86 ["bin", "lib", "lib32", "lib64", "sbin"])) 87 88 return compat.UniqueFrozenset(map(os.path.normpath, paths))
89 90
91 -def _ComputeWrongFileStoragePaths(paths, 92 _forbidden=_GetForbiddenFileStoragePaths()):
93 """Cross-checks a list of paths for prefixes considered bad. 94 95 Some paths, e.g. "/bin", should not be used for file storage. 96 97 @type paths: list 98 @param paths: List of paths to be checked 99 @rtype: list 100 @return: Sorted list of paths for which the user should be warned 101 102 """ 103 def _Check(path): 104 return (not os.path.isabs(path) or 105 path in _forbidden or 106 filter(lambda p: utils.IsBelowDir(p, path), _forbidden))
107 108 return utils.NiceSort(filter(_Check, map(os.path.normpath, paths))) 109 110
111 -def ComputeWrongFileStoragePaths(_filename=pathutils.FILE_STORAGE_PATHS_FILE):
112 """Returns a list of file storage paths whose prefix is considered bad. 113 114 See L{_ComputeWrongFileStoragePaths}. 115 116 """ 117 return _ComputeWrongFileStoragePaths(_LoadAllowedFileStoragePaths(_filename))
118 119
120 -def _CheckFileStoragePath(path, allowed, exact_match_ok=False):
121 """Checks if a path is in a list of allowed paths for file storage. 122 123 @type path: string 124 @param path: Path to check 125 @type allowed: list 126 @param allowed: List of allowed paths 127 @type exact_match_ok: bool 128 @param exact_match_ok: whether or not it is okay when the path is exactly 129 equal to an allowed path and not a subdir of it 130 @raise errors.FileStoragePathError: If the path is not allowed 131 132 """ 133 if not os.path.isabs(path): 134 raise errors.FileStoragePathError("File storage path must be absolute," 135 " got '%s'" % path) 136 137 for i in allowed: 138 if not os.path.isabs(i): 139 logging.info("Ignoring relative path '%s' for file storage", i) 140 continue 141 142 if exact_match_ok: 143 if os.path.normpath(i) == os.path.normpath(path): 144 break 145 146 if utils.IsBelowDir(i, path): 147 break 148 else: 149 raise errors.FileStoragePathError("Path '%s' is not acceptable for file" 150 " storage" % path)
151 152
153 -def _LoadAllowedFileStoragePaths(filename):
154 """Loads file containing allowed file storage paths. 155 156 @rtype: list 157 @return: List of allowed paths (can be an empty list) 158 159 """ 160 try: 161 contents = utils.ReadFile(filename) 162 except EnvironmentError: 163 return [] 164 else: 165 return utils.FilterEmptyLinesAndComments(contents)
166 167
168 -def CheckFileStoragePathAcceptance( 169 path, _filename=pathutils.FILE_STORAGE_PATHS_FILE, 170 exact_match_ok=False):
171 """Checks if a path is allowed for file storage. 172 173 @type path: string 174 @param path: Path to check 175 @raise errors.FileStoragePathError: If the path is not allowed 176 177 """ 178 allowed = _LoadAllowedFileStoragePaths(_filename) 179 if not allowed: 180 raise errors.FileStoragePathError("No paths are valid or path file '%s'" 181 " was not accessible." % _filename) 182 183 if _ComputeWrongFileStoragePaths([path]): 184 raise errors.FileStoragePathError("Path '%s' uses a forbidden prefix" % 185 path) 186 187 _CheckFileStoragePath(path, allowed, exact_match_ok=exact_match_ok)
188 189
190 -def _CheckFileStoragePathExistance(path):
191 """Checks whether the given path is usable on the file system. 192 193 This checks wether the path is existing, a directory and writable. 194 195 @type path: string 196 @param path: path to check 197 198 """ 199 if not os.path.isdir(path): 200 raise errors.FileStoragePathError("Path '%s' does not exist or is not a" 201 " directory." % path) 202 if not os.access(path, os.W_OK): 203 raise errors.FileStoragePathError("Path '%s' is not writable" % path)
204 205
206 -def CheckFileStoragePath( 207 path, _allowed_paths_file=pathutils.FILE_STORAGE_PATHS_FILE):
208 """Checks whether the path exists and is acceptable to use. 209 210 Can be used for any file-based storage, for example shared-file storage. 211 212 @type path: string 213 @param path: path to check 214 @rtype: string 215 @returns: error message if the path is not ready to use 216 217 """ 218 try: 219 CheckFileStoragePathAcceptance(path, _filename=_allowed_paths_file, 220 exact_match_ok=True) 221 except errors.FileStoragePathError as e: 222 return str(e) 223 if not os.path.isdir(path): 224 return "Path '%s' is not existing or not a directory." % path 225 if not os.access(path, os.W_OK): 226 return "Path '%s' is not writable" % path
227