Statistics
| Branch: | Tag: | Revision:

root / lib / storage / filestorage.py @ 8f8442d6

History | View | Annotate | Download (6.1 kB)

1 820bade9 Helga Velroyen
#
2 820bade9 Helga Velroyen
#
3 820bade9 Helga Velroyen
4 820bade9 Helga Velroyen
# Copyright (C) 2013 Google Inc.
5 820bade9 Helga Velroyen
#
6 820bade9 Helga Velroyen
# This program is free software; you can redistribute it and/or modify
7 820bade9 Helga Velroyen
# it under the terms of the GNU General Public License as published by
8 820bade9 Helga Velroyen
# the Free Software Foundation; either version 2 of the License, or
9 820bade9 Helga Velroyen
# (at your option) any later version.
10 820bade9 Helga Velroyen
#
11 820bade9 Helga Velroyen
# This program is distributed in the hope that it will be useful, but
12 820bade9 Helga Velroyen
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 820bade9 Helga Velroyen
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 820bade9 Helga Velroyen
# General Public License for more details.
15 820bade9 Helga Velroyen
#
16 820bade9 Helga Velroyen
# You should have received a copy of the GNU General Public License
17 820bade9 Helga Velroyen
# along with this program; if not, write to the Free Software
18 820bade9 Helga Velroyen
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 820bade9 Helga Velroyen
# 02110-1301, USA.
20 820bade9 Helga Velroyen
21 820bade9 Helga Velroyen
22 820bade9 Helga Velroyen
"""File storage functions.
23 820bade9 Helga Velroyen

24 820bade9 Helga Velroyen
"""
25 820bade9 Helga Velroyen
26 13a6c760 Helga Velroyen
import logging
27 5d94c034 Helga Velroyen
import os
28 820bade9 Helga Velroyen
29 13a6c760 Helga Velroyen
from ganeti import compat
30 13669ecd Helga Velroyen
from ganeti import constants
31 5d94c034 Helga Velroyen
from ganeti import errors
32 13a6c760 Helga Velroyen
from ganeti import pathutils
33 13a6c760 Helga Velroyen
from ganeti import utils
34 820bade9 Helga Velroyen
35 820bade9 Helga Velroyen
36 e798d484 Helga Velroyen
def GetFileStorageSpaceInfo(path):
37 820bade9 Helga Velroyen
  """Retrieves the free and total space of the device where the file is
38 820bade9 Helga Velroyen
     located.
39 820bade9 Helga Velroyen

40 820bade9 Helga Velroyen
     @type path: string
41 820bade9 Helga Velroyen
     @param path: Path of the file whose embracing device's capacity is
42 820bade9 Helga Velroyen
       reported.
43 5d94c034 Helga Velroyen
     @return: a dictionary containing 'vg_size' and 'vg_free' given in MebiBytes
44 5d94c034 Helga Velroyen

45 820bade9 Helga Velroyen
  """
46 5d94c034 Helga Velroyen
  try:
47 5d94c034 Helga Velroyen
    result = os.statvfs(path)
48 5d94c034 Helga Velroyen
    free = (result.f_frsize * result.f_bavail) / (1024 * 1024)
49 5d94c034 Helga Velroyen
    size = (result.f_frsize * result.f_blocks) / (1024 * 1024)
50 13669ecd Helga Velroyen
    return {"type": constants.ST_FILE,
51 13669ecd Helga Velroyen
            "name": path,
52 32389d91 Helga Velroyen
            "storage_size": size,
53 32389d91 Helga Velroyen
            "storage_free": free}
54 5d94c034 Helga Velroyen
  except OSError, e:
55 5d94c034 Helga Velroyen
    raise errors.CommandError("Failed to retrieve file system information about"
56 5d94c034 Helga Velroyen
                              " path: %s - %s" % (path, e.strerror))
57 13a6c760 Helga Velroyen
58 13a6c760 Helga Velroyen
59 13a6c760 Helga Velroyen
def _GetForbiddenFileStoragePaths():
60 13a6c760 Helga Velroyen
  """Builds a list of path prefixes which shouldn't be used for file storage.
61 13a6c760 Helga Velroyen

62 13a6c760 Helga Velroyen
  @rtype: frozenset
63 13a6c760 Helga Velroyen

64 13a6c760 Helga Velroyen
  """
65 13a6c760 Helga Velroyen
  paths = set([
66 13a6c760 Helga Velroyen
    "/boot",
67 13a6c760 Helga Velroyen
    "/dev",
68 13a6c760 Helga Velroyen
    "/etc",
69 13a6c760 Helga Velroyen
    "/home",
70 13a6c760 Helga Velroyen
    "/proc",
71 13a6c760 Helga Velroyen
    "/root",
72 13a6c760 Helga Velroyen
    "/sys",
73 13a6c760 Helga Velroyen
    ])
74 13a6c760 Helga Velroyen
75 13a6c760 Helga Velroyen
  for prefix in ["", "/usr", "/usr/local"]:
76 13a6c760 Helga Velroyen
    paths.update(map(lambda s: "%s/%s" % (prefix, s),
77 13a6c760 Helga Velroyen
                     ["bin", "lib", "lib32", "lib64", "sbin"]))
78 13a6c760 Helga Velroyen
79 13a6c760 Helga Velroyen
  return compat.UniqueFrozenset(map(os.path.normpath, paths))
80 13a6c760 Helga Velroyen
81 13a6c760 Helga Velroyen
82 13a6c760 Helga Velroyen
def _ComputeWrongFileStoragePaths(paths,
83 13a6c760 Helga Velroyen
                                  _forbidden=_GetForbiddenFileStoragePaths()):
84 13a6c760 Helga Velroyen
  """Cross-checks a list of paths for prefixes considered bad.
85 13a6c760 Helga Velroyen

86 13a6c760 Helga Velroyen
  Some paths, e.g. "/bin", should not be used for file storage.
87 13a6c760 Helga Velroyen

88 13a6c760 Helga Velroyen
  @type paths: list
89 13a6c760 Helga Velroyen
  @param paths: List of paths to be checked
90 13a6c760 Helga Velroyen
  @rtype: list
91 13a6c760 Helga Velroyen
  @return: Sorted list of paths for which the user should be warned
92 13a6c760 Helga Velroyen

93 13a6c760 Helga Velroyen
  """
94 13a6c760 Helga Velroyen
  def _Check(path):
95 13a6c760 Helga Velroyen
    return (not os.path.isabs(path) or
96 13a6c760 Helga Velroyen
            path in _forbidden or
97 13a6c760 Helga Velroyen
            filter(lambda p: utils.IsBelowDir(p, path), _forbidden))
98 13a6c760 Helga Velroyen
99 13a6c760 Helga Velroyen
  return utils.NiceSort(filter(_Check, map(os.path.normpath, paths)))
100 13a6c760 Helga Velroyen
101 13a6c760 Helga Velroyen
102 13a6c760 Helga Velroyen
def ComputeWrongFileStoragePaths(_filename=pathutils.FILE_STORAGE_PATHS_FILE):
103 13a6c760 Helga Velroyen
  """Returns a list of file storage paths whose prefix is considered bad.
104 13a6c760 Helga Velroyen

105 13a6c760 Helga Velroyen
  See L{_ComputeWrongFileStoragePaths}.
106 13a6c760 Helga Velroyen

107 13a6c760 Helga Velroyen
  """
108 13a6c760 Helga Velroyen
  return _ComputeWrongFileStoragePaths(_LoadAllowedFileStoragePaths(_filename))
109 13a6c760 Helga Velroyen
110 13a6c760 Helga Velroyen
111 9c1c3c19 Helga Velroyen
def _CheckFileStoragePath(path, allowed, exact_match_ok=False):
112 13a6c760 Helga Velroyen
  """Checks if a path is in a list of allowed paths for file storage.
113 13a6c760 Helga Velroyen

114 13a6c760 Helga Velroyen
  @type path: string
115 13a6c760 Helga Velroyen
  @param path: Path to check
116 13a6c760 Helga Velroyen
  @type allowed: list
117 13a6c760 Helga Velroyen
  @param allowed: List of allowed paths
118 9c1c3c19 Helga Velroyen
  @type exact_match_ok: bool
119 9c1c3c19 Helga Velroyen
  @param exact_match_ok: whether or not it is okay when the path is exactly
120 9c1c3c19 Helga Velroyen
      equal to an allowed path and not a subdir of it
121 13a6c760 Helga Velroyen
  @raise errors.FileStoragePathError: If the path is not allowed
122 13a6c760 Helga Velroyen

123 13a6c760 Helga Velroyen
  """
124 13a6c760 Helga Velroyen
  if not os.path.isabs(path):
125 13a6c760 Helga Velroyen
    raise errors.FileStoragePathError("File storage path must be absolute,"
126 13a6c760 Helga Velroyen
                                      " got '%s'" % path)
127 13a6c760 Helga Velroyen
128 13a6c760 Helga Velroyen
  for i in allowed:
129 13a6c760 Helga Velroyen
    if not os.path.isabs(i):
130 13a6c760 Helga Velroyen
      logging.info("Ignoring relative path '%s' for file storage", i)
131 13a6c760 Helga Velroyen
      continue
132 13a6c760 Helga Velroyen
133 9c1c3c19 Helga Velroyen
    if exact_match_ok:
134 9c1c3c19 Helga Velroyen
      if os.path.normpath(i) == os.path.normpath(path):
135 9c1c3c19 Helga Velroyen
        break
136 9c1c3c19 Helga Velroyen
137 13a6c760 Helga Velroyen
    if utils.IsBelowDir(i, path):
138 13a6c760 Helga Velroyen
      break
139 13a6c760 Helga Velroyen
  else:
140 13a6c760 Helga Velroyen
    raise errors.FileStoragePathError("Path '%s' is not acceptable for file"
141 13a6c760 Helga Velroyen
                                      " storage" % path)
142 13a6c760 Helga Velroyen
143 13a6c760 Helga Velroyen
144 13a6c760 Helga Velroyen
def _LoadAllowedFileStoragePaths(filename):
145 13a6c760 Helga Velroyen
  """Loads file containing allowed file storage paths.
146 13a6c760 Helga Velroyen

147 13a6c760 Helga Velroyen
  @rtype: list
148 13a6c760 Helga Velroyen
  @return: List of allowed paths (can be an empty list)
149 13a6c760 Helga Velroyen

150 13a6c760 Helga Velroyen
  """
151 13a6c760 Helga Velroyen
  try:
152 13a6c760 Helga Velroyen
    contents = utils.ReadFile(filename)
153 13a6c760 Helga Velroyen
  except EnvironmentError:
154 13a6c760 Helga Velroyen
    return []
155 13a6c760 Helga Velroyen
  else:
156 13a6c760 Helga Velroyen
    return utils.FilterEmptyLinesAndComments(contents)
157 13a6c760 Helga Velroyen
158 13a6c760 Helga Velroyen
159 13a6c760 Helga Velroyen
def CheckFileStoragePathAcceptance(
160 9c1c3c19 Helga Velroyen
    path, _filename=pathutils.FILE_STORAGE_PATHS_FILE,
161 9c1c3c19 Helga Velroyen
    exact_match_ok=False):
162 13a6c760 Helga Velroyen
  """Checks if a path is allowed for file storage.
163 13a6c760 Helga Velroyen

164 13a6c760 Helga Velroyen
  @type path: string
165 13a6c760 Helga Velroyen
  @param path: Path to check
166 13a6c760 Helga Velroyen
  @raise errors.FileStoragePathError: If the path is not allowed
167 13a6c760 Helga Velroyen

168 13a6c760 Helga Velroyen
  """
169 13a6c760 Helga Velroyen
  allowed = _LoadAllowedFileStoragePaths(_filename)
170 13a6c760 Helga Velroyen
171 13a6c760 Helga Velroyen
  if _ComputeWrongFileStoragePaths([path]):
172 13a6c760 Helga Velroyen
    raise errors.FileStoragePathError("Path '%s' uses a forbidden prefix" %
173 13a6c760 Helga Velroyen
                                      path)
174 13a6c760 Helga Velroyen
175 9c1c3c19 Helga Velroyen
  _CheckFileStoragePath(path, allowed, exact_match_ok=exact_match_ok)
176 9c1c3c19 Helga Velroyen
177 9c1c3c19 Helga Velroyen
178 9c1c3c19 Helga Velroyen
def _CheckFileStoragePathExistance(path):
179 9c1c3c19 Helga Velroyen
  """Checks whether the given path is usable on the file system.
180 9c1c3c19 Helga Velroyen

181 9c1c3c19 Helga Velroyen
  This checks wether the path is existing, a directory and writable.
182 9c1c3c19 Helga Velroyen

183 9c1c3c19 Helga Velroyen
  @type path: string
184 9c1c3c19 Helga Velroyen
  @param path: path to check
185 9c1c3c19 Helga Velroyen

186 9c1c3c19 Helga Velroyen
  """
187 9c1c3c19 Helga Velroyen
  if not os.path.isdir(path):
188 9c1c3c19 Helga Velroyen
    raise errors.FileStoragePathError("Path '%s' is not exisiting or not a"
189 9c1c3c19 Helga Velroyen
                                      " directory." % path)
190 9c1c3c19 Helga Velroyen
  if not os.access(path, os.W_OK):
191 9c1c3c19 Helga Velroyen
    raise errors.FileStoragePathError("Path '%s' is not writable" % path)
192 9c1c3c19 Helga Velroyen
193 9c1c3c19 Helga Velroyen
194 9c1c3c19 Helga Velroyen
def CheckFileStoragePath(
195 9c1c3c19 Helga Velroyen
    path, _allowed_paths_file=pathutils.FILE_STORAGE_PATHS_FILE):
196 9c1c3c19 Helga Velroyen
  """Checks whether the path exists and is acceptable to use.
197 9c1c3c19 Helga Velroyen

198 9c1c3c19 Helga Velroyen
  @type path: string
199 9c1c3c19 Helga Velroyen
  @param path: path to check
200 9c1c3c19 Helga Velroyen
  @rtype: string
201 9c1c3c19 Helga Velroyen
  @returns: error message if the path is not ready to use
202 9c1c3c19 Helga Velroyen

203 9c1c3c19 Helga Velroyen
  """
204 9c1c3c19 Helga Velroyen
  try:
205 9c1c3c19 Helga Velroyen
    CheckFileStoragePathAcceptance(path, _filename=_allowed_paths_file,
206 9c1c3c19 Helga Velroyen
                                   exact_match_ok=True)
207 9c1c3c19 Helga Velroyen
  except errors.FileStoragePathError, e:
208 9c1c3c19 Helga Velroyen
    return e.message
209 9c1c3c19 Helga Velroyen
  if not os.path.isdir(path):
210 9c1c3c19 Helga Velroyen
    return "Path '%s' is not exisiting or not a directory." % path
211 9c1c3c19 Helga Velroyen
  if not os.access(path, os.W_OK):
212 9c1c3c19 Helga Velroyen
    return "Path '%s' is not writable" % path