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 """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
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
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
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
118
119
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
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
188
189
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
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