1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """File storage functions.
23
24 """
25
26 import logging
27 import os
28
29 from ganeti import compat
30 from ganeti import constants
31 from ganeti import errors
32 from ganeti import pathutils
33 from ganeti import utils
34
35
37 """Retrieves the free and total space of the device where the file is
38 located.
39
40 @type path: string
41 @param path: Path of the file whose embracing device's capacity is
42 reported.
43 @return: a dictionary containing 'vg_size' and 'vg_free' given in MebiBytes
44
45 """
46 try:
47 result = os.statvfs(path)
48 free = (result.f_frsize * result.f_bavail) / (1024 * 1024)
49 size = (result.f_frsize * result.f_blocks) / (1024 * 1024)
50 return {"type": constants.ST_FILE,
51 "name": path,
52 "storage_size": size,
53 "storage_free": free}
54 except OSError, e:
55 raise errors.CommandError("Failed to retrieve file system information about"
56 " path: %s - %s" % (path, e.strerror))
57
58
60 """Builds a list of path prefixes which shouldn't be used for file storage.
61
62 @rtype: frozenset
63
64 """
65 paths = set([
66 "/boot",
67 "/dev",
68 "/etc",
69 "/home",
70 "/proc",
71 "/root",
72 "/sys",
73 ])
74
75 for prefix in ["", "/usr", "/usr/local"]:
76 paths.update(map(lambda s: "%s/%s" % (prefix, s),
77 ["bin", "lib", "lib32", "lib64", "sbin"]))
78
79 return compat.UniqueFrozenset(map(os.path.normpath, paths))
80
81
84 """Cross-checks a list of paths for prefixes considered bad.
85
86 Some paths, e.g. "/bin", should not be used for file storage.
87
88 @type paths: list
89 @param paths: List of paths to be checked
90 @rtype: list
91 @return: Sorted list of paths for which the user should be warned
92
93 """
94 def _Check(path):
95 return (not os.path.isabs(path) or
96 path in _forbidden or
97 filter(lambda p: utils.IsBelowDir(p, path), _forbidden))
98
99 return utils.NiceSort(filter(_Check, map(os.path.normpath, paths)))
100
101
109
110
112 """Checks if a path is in a list of allowed paths for file storage.
113
114 @type path: string
115 @param path: Path to check
116 @type allowed: list
117 @param allowed: List of allowed paths
118 @type exact_match_ok: bool
119 @param exact_match_ok: whether or not it is okay when the path is exactly
120 equal to an allowed path and not a subdir of it
121 @raise errors.FileStoragePathError: If the path is not allowed
122
123 """
124 if not os.path.isabs(path):
125 raise errors.FileStoragePathError("File storage path must be absolute,"
126 " got '%s'" % path)
127
128 for i in allowed:
129 if not os.path.isabs(i):
130 logging.info("Ignoring relative path '%s' for file storage", i)
131 continue
132
133 if exact_match_ok:
134 if os.path.normpath(i) == os.path.normpath(path):
135 break
136
137 if utils.IsBelowDir(i, path):
138 break
139 else:
140 raise errors.FileStoragePathError("Path '%s' is not acceptable for file"
141 " storage" % path)
142
143
145 """Loads file containing allowed file storage paths.
146
147 @rtype: list
148 @return: List of allowed paths (can be an empty list)
149
150 """
151 try:
152 contents = utils.ReadFile(filename)
153 except EnvironmentError:
154 return []
155 else:
156 return utils.FilterEmptyLinesAndComments(contents)
157
158
179
180
182 """Checks whether the given path is usable on the file system.
183
184 This checks wether the path is existing, a directory and writable.
185
186 @type path: string
187 @param path: path to check
188
189 """
190 if not os.path.isdir(path):
191 raise errors.FileStoragePathError("Path '%s' is not existing or not a"
192 " directory." % path)
193 if not os.access(path, os.W_OK):
194 raise errors.FileStoragePathError("Path '%s' is not writable" % path)
195
196
199 """Checks whether the path exists and is acceptable to use.
200
201 Can be used for any file-based storage, for example shared-file storage.
202
203 @type path: string
204 @param path: path to check
205 @rtype: string
206 @returns: error message if the path is not ready to use
207
208 """
209 try:
210 CheckFileStoragePathAcceptance(path, _filename=_allowed_paths_file,
211 exact_match_ok=True)
212 except errors.FileStoragePathError as e:
213 return str(e)
214 if not os.path.isdir(path):
215 return "Path '%s' is not exisiting or not a directory." % path
216 if not os.access(path, os.W_OK):
217 return "Path '%s' is not writable" % path
218