root / lib / storage.py @ 7a95a954
History | View | Annotate | Download (9.7 kB)
1 | ac2d0fe4 | Michael Hanselmann | #
|
---|---|---|---|
2 | ac2d0fe4 | Michael Hanselmann | #
|
3 | ac2d0fe4 | Michael Hanselmann | |
4 | ac2d0fe4 | Michael Hanselmann | # Copyright (C) 2009 Google Inc.
|
5 | ac2d0fe4 | Michael Hanselmann | #
|
6 | ac2d0fe4 | Michael Hanselmann | # This program is free software; you can redistribute it and/or modify
|
7 | ac2d0fe4 | Michael Hanselmann | # it under the terms of the GNU General Public License as published by
|
8 | ac2d0fe4 | Michael Hanselmann | # the Free Software Foundation; either version 2 of the License, or
|
9 | ac2d0fe4 | Michael Hanselmann | # (at your option) any later version.
|
10 | ac2d0fe4 | Michael Hanselmann | #
|
11 | ac2d0fe4 | Michael Hanselmann | # This program is distributed in the hope that it will be useful, but
|
12 | ac2d0fe4 | Michael Hanselmann | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | ac2d0fe4 | Michael Hanselmann | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | ac2d0fe4 | Michael Hanselmann | # General Public License for more details.
|
15 | ac2d0fe4 | Michael Hanselmann | #
|
16 | ac2d0fe4 | Michael Hanselmann | # You should have received a copy of the GNU General Public License
|
17 | ac2d0fe4 | Michael Hanselmann | # along with this program; if not, write to the Free Software
|
18 | ac2d0fe4 | Michael Hanselmann | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | ac2d0fe4 | Michael Hanselmann | # 02110-1301, USA.
|
20 | ac2d0fe4 | Michael Hanselmann | |
21 | ac2d0fe4 | Michael Hanselmann | |
22 | ac2d0fe4 | Michael Hanselmann | """Storage container abstraction.
|
23 | ac2d0fe4 | Michael Hanselmann |
|
24 | ac2d0fe4 | Michael Hanselmann | """
|
25 | ac2d0fe4 | Michael Hanselmann | |
26 | ac2d0fe4 | Michael Hanselmann | |
27 | ac2d0fe4 | Michael Hanselmann | import logging |
28 | ac2d0fe4 | Michael Hanselmann | |
29 | ac2d0fe4 | Michael Hanselmann | from ganeti import errors |
30 | ac2d0fe4 | Michael Hanselmann | from ganeti import constants |
31 | ac2d0fe4 | Michael Hanselmann | from ganeti import utils |
32 | ac2d0fe4 | Michael Hanselmann | |
33 | ac2d0fe4 | Michael Hanselmann | |
34 | ac2d0fe4 | Michael Hanselmann | def _ParseSize(value): |
35 | ac2d0fe4 | Michael Hanselmann | return int(round(float(value), 0)) |
36 | ac2d0fe4 | Michael Hanselmann | |
37 | ac2d0fe4 | Michael Hanselmann | |
38 | ac2d0fe4 | Michael Hanselmann | class _Base: |
39 | ac2d0fe4 | Michael Hanselmann | """Base class for storage abstraction.
|
40 | ac2d0fe4 | Michael Hanselmann |
|
41 | ac2d0fe4 | Michael Hanselmann | """
|
42 | ac2d0fe4 | Michael Hanselmann | def List(self, name, fields): |
43 | ac2d0fe4 | Michael Hanselmann | """Returns a list of all entities within the storage unit.
|
44 | ac2d0fe4 | Michael Hanselmann |
|
45 | ac2d0fe4 | Michael Hanselmann | @type name: string or None
|
46 | ac2d0fe4 | Michael Hanselmann | @param name: Entity name or None for all
|
47 | ac2d0fe4 | Michael Hanselmann | @type fields: list
|
48 | ac2d0fe4 | Michael Hanselmann | @param fields: List with all requested result fields (order is preserved)
|
49 | ac2d0fe4 | Michael Hanselmann |
|
50 | ac2d0fe4 | Michael Hanselmann | """
|
51 | ac2d0fe4 | Michael Hanselmann | raise NotImplementedError() |
52 | ac2d0fe4 | Michael Hanselmann | |
53 | 9b648ee7 | Michael Hanselmann | def Modify(self, name, changes): |
54 | 9b648ee7 | Michael Hanselmann | """Modifies an entity within the storage unit.
|
55 | 9b648ee7 | Michael Hanselmann |
|
56 | 9b648ee7 | Michael Hanselmann | @type name: string
|
57 | 9b648ee7 | Michael Hanselmann | @param name: Entity name
|
58 | 9b648ee7 | Michael Hanselmann | @type changes: dict
|
59 | 9b648ee7 | Michael Hanselmann | @param changes: New field values
|
60 | 9b648ee7 | Michael Hanselmann |
|
61 | 9b648ee7 | Michael Hanselmann | """
|
62 | 9b648ee7 | Michael Hanselmann | # Don't raise an error if no changes are requested
|
63 | 9b648ee7 | Michael Hanselmann | if changes:
|
64 | 9b648ee7 | Michael Hanselmann | raise errors.ProgrammerError("Unable to modify the following" |
65 | 9b648ee7 | Michael Hanselmann | "fields: %r" % (changes.keys(), ))
|
66 | 9b648ee7 | Michael Hanselmann | |
67 | ac2d0fe4 | Michael Hanselmann | |
68 | ac2d0fe4 | Michael Hanselmann | class FileStorage(_Base): |
69 | ac2d0fe4 | Michael Hanselmann | """File storage unit.
|
70 | ac2d0fe4 | Michael Hanselmann |
|
71 | ac2d0fe4 | Michael Hanselmann | """
|
72 | ac2d0fe4 | Michael Hanselmann | def __init__(self, paths): |
73 | ac2d0fe4 | Michael Hanselmann | """Initializes this class.
|
74 | ac2d0fe4 | Michael Hanselmann |
|
75 | ac2d0fe4 | Michael Hanselmann | @type paths: list
|
76 | ac2d0fe4 | Michael Hanselmann | @param paths: List of file storage paths
|
77 | ac2d0fe4 | Michael Hanselmann |
|
78 | ac2d0fe4 | Michael Hanselmann | """
|
79 | ac2d0fe4 | Michael Hanselmann | self._paths = paths
|
80 | ac2d0fe4 | Michael Hanselmann | |
81 | ac2d0fe4 | Michael Hanselmann | def List(self, name, fields): |
82 | ac2d0fe4 | Michael Hanselmann | """Returns a list of all entities within the storage unit.
|
83 | ac2d0fe4 | Michael Hanselmann |
|
84 | ac2d0fe4 | Michael Hanselmann | See L{_Base.List}.
|
85 | ac2d0fe4 | Michael Hanselmann |
|
86 | ac2d0fe4 | Michael Hanselmann | """
|
87 | ac2d0fe4 | Michael Hanselmann | rows = [] |
88 | ac2d0fe4 | Michael Hanselmann | |
89 | ac2d0fe4 | Michael Hanselmann | if name is None: |
90 | ac2d0fe4 | Michael Hanselmann | paths = self._paths
|
91 | ac2d0fe4 | Michael Hanselmann | else:
|
92 | ac2d0fe4 | Michael Hanselmann | paths = [name] |
93 | ac2d0fe4 | Michael Hanselmann | |
94 | ac2d0fe4 | Michael Hanselmann | for path in paths: |
95 | ac2d0fe4 | Michael Hanselmann | rows.append(self._ListInner(path, fields))
|
96 | ac2d0fe4 | Michael Hanselmann | |
97 | ac2d0fe4 | Michael Hanselmann | return rows
|
98 | ac2d0fe4 | Michael Hanselmann | |
99 | ac2d0fe4 | Michael Hanselmann | @staticmethod
|
100 | ac2d0fe4 | Michael Hanselmann | def _ListInner(path, fields): |
101 | ac2d0fe4 | Michael Hanselmann | """Gathers requested information from directory.
|
102 | ac2d0fe4 | Michael Hanselmann |
|
103 | ac2d0fe4 | Michael Hanselmann | @type path: string
|
104 | ac2d0fe4 | Michael Hanselmann | @param path: Path to directory
|
105 | ac2d0fe4 | Michael Hanselmann | @type fields: list
|
106 | ac2d0fe4 | Michael Hanselmann | @param fields: Requested fields
|
107 | ac2d0fe4 | Michael Hanselmann |
|
108 | ac2d0fe4 | Michael Hanselmann | """
|
109 | ac2d0fe4 | Michael Hanselmann | values = [] |
110 | ac2d0fe4 | Michael Hanselmann | |
111 | ac2d0fe4 | Michael Hanselmann | # Pre-calculate information in case it's requested more than once
|
112 | 6032697c | Michael Hanselmann | if constants.SF_USED in fields: |
113 | ac2d0fe4 | Michael Hanselmann | dirsize = utils.CalculateDirectorySize(path) |
114 | ac2d0fe4 | Michael Hanselmann | else:
|
115 | ac2d0fe4 | Michael Hanselmann | dirsize = None
|
116 | ac2d0fe4 | Michael Hanselmann | |
117 | 6032697c | Michael Hanselmann | if constants.SF_FREE in fields: |
118 | ac2d0fe4 | Michael Hanselmann | fsfree = utils.GetFreeFilesystemSpace(path) |
119 | ac2d0fe4 | Michael Hanselmann | else:
|
120 | ac2d0fe4 | Michael Hanselmann | fsfree = None
|
121 | ac2d0fe4 | Michael Hanselmann | |
122 | 6032697c | Michael Hanselmann | # Make sure to update constants.VALID_STORAGE_FIELDS when changing fields.
|
123 | ac2d0fe4 | Michael Hanselmann | for field_name in fields: |
124 | 6032697c | Michael Hanselmann | if field_name == constants.SF_NAME:
|
125 | ac2d0fe4 | Michael Hanselmann | values.append(path) |
126 | ac2d0fe4 | Michael Hanselmann | |
127 | 6032697c | Michael Hanselmann | elif field_name == constants.SF_USED:
|
128 | ac2d0fe4 | Michael Hanselmann | values.append(dirsize) |
129 | ac2d0fe4 | Michael Hanselmann | |
130 | 6032697c | Michael Hanselmann | elif field_name == constants.SF_FREE:
|
131 | ac2d0fe4 | Michael Hanselmann | values.append(fsfree) |
132 | ac2d0fe4 | Michael Hanselmann | |
133 | ac2d0fe4 | Michael Hanselmann | else:
|
134 | ac2d0fe4 | Michael Hanselmann | raise errors.StorageError("Unknown field: %r" % field_name) |
135 | ac2d0fe4 | Michael Hanselmann | |
136 | ac2d0fe4 | Michael Hanselmann | return values
|
137 | ac2d0fe4 | Michael Hanselmann | |
138 | ac2d0fe4 | Michael Hanselmann | |
139 | ac2d0fe4 | Michael Hanselmann | class _LvmBase(_Base): |
140 | ac2d0fe4 | Michael Hanselmann | """Base class for LVM storage containers.
|
141 | ac2d0fe4 | Michael Hanselmann |
|
142 | ac2d0fe4 | Michael Hanselmann | """
|
143 | ac2d0fe4 | Michael Hanselmann | LIST_SEP = "|"
|
144 | ac2d0fe4 | Michael Hanselmann | LIST_COMMAND = None
|
145 | ac2d0fe4 | Michael Hanselmann | LIST_FIELDS = None
|
146 | ac2d0fe4 | Michael Hanselmann | |
147 | ac2d0fe4 | Michael Hanselmann | def List(self, name, wanted_field_names): |
148 | ac2d0fe4 | Michael Hanselmann | """Returns a list of all entities within the storage unit.
|
149 | ac2d0fe4 | Michael Hanselmann |
|
150 | ac2d0fe4 | Michael Hanselmann | See L{_Base.List}.
|
151 | ac2d0fe4 | Michael Hanselmann |
|
152 | ac2d0fe4 | Michael Hanselmann | """
|
153 | ac2d0fe4 | Michael Hanselmann | # Get needed LVM fields
|
154 | ac2d0fe4 | Michael Hanselmann | lvm_fields = self._GetLvmFields(self.LIST_FIELDS, wanted_field_names) |
155 | ac2d0fe4 | Michael Hanselmann | |
156 | ac2d0fe4 | Michael Hanselmann | # Build LVM command
|
157 | ac2d0fe4 | Michael Hanselmann | cmd_args = self._BuildListCommand(self.LIST_COMMAND, self.LIST_SEP, |
158 | ac2d0fe4 | Michael Hanselmann | lvm_fields, name) |
159 | ac2d0fe4 | Michael Hanselmann | |
160 | ac2d0fe4 | Michael Hanselmann | # Run LVM command
|
161 | ac2d0fe4 | Michael Hanselmann | cmd_result = self._RunListCommand(cmd_args)
|
162 | ac2d0fe4 | Michael Hanselmann | |
163 | ac2d0fe4 | Michael Hanselmann | # Split and rearrange LVM command output
|
164 | ac2d0fe4 | Michael Hanselmann | return self._BuildList(self._SplitList(cmd_result, self.LIST_SEP, |
165 | ac2d0fe4 | Michael Hanselmann | len(lvm_fields)),
|
166 | ac2d0fe4 | Michael Hanselmann | self.LIST_FIELDS,
|
167 | ac2d0fe4 | Michael Hanselmann | wanted_field_names, |
168 | ac2d0fe4 | Michael Hanselmann | lvm_fields) |
169 | ac2d0fe4 | Michael Hanselmann | |
170 | ac2d0fe4 | Michael Hanselmann | @staticmethod
|
171 | ac2d0fe4 | Michael Hanselmann | def _GetLvmFields(fields_def, wanted_field_names): |
172 | ac2d0fe4 | Michael Hanselmann | """Returns unique list of fields wanted from LVM command.
|
173 | ac2d0fe4 | Michael Hanselmann |
|
174 | ac2d0fe4 | Michael Hanselmann | @type fields_def: list
|
175 | ac2d0fe4 | Michael Hanselmann | @param fields_def: Field definitions
|
176 | ac2d0fe4 | Michael Hanselmann | @type wanted_field_names: list
|
177 | ac2d0fe4 | Michael Hanselmann | @param wanted_field_names: List of requested fields
|
178 | ac2d0fe4 | Michael Hanselmann |
|
179 | ac2d0fe4 | Michael Hanselmann | """
|
180 | ac2d0fe4 | Michael Hanselmann | field_to_idx = dict([(field_name, idx)
|
181 | ac2d0fe4 | Michael Hanselmann | for (idx, (field_name, _, _)) in enumerate(fields_def)]) |
182 | ac2d0fe4 | Michael Hanselmann | |
183 | ac2d0fe4 | Michael Hanselmann | lvm_fields = [] |
184 | ac2d0fe4 | Michael Hanselmann | |
185 | ac2d0fe4 | Michael Hanselmann | for field_name in wanted_field_names: |
186 | ac2d0fe4 | Michael Hanselmann | try:
|
187 | ac2d0fe4 | Michael Hanselmann | idx = field_to_idx[field_name] |
188 | ac2d0fe4 | Michael Hanselmann | except IndexError: |
189 | ac2d0fe4 | Michael Hanselmann | raise errors.StorageError("Unknown field: %r" % field_name) |
190 | ac2d0fe4 | Michael Hanselmann | |
191 | ac2d0fe4 | Michael Hanselmann | (_, lvm_name, _) = fields_def[idx] |
192 | ac2d0fe4 | Michael Hanselmann | |
193 | ac2d0fe4 | Michael Hanselmann | lvm_fields.append(lvm_name) |
194 | ac2d0fe4 | Michael Hanselmann | |
195 | ac2d0fe4 | Michael Hanselmann | return utils.UniqueSequence(lvm_fields)
|
196 | ac2d0fe4 | Michael Hanselmann | |
197 | ac2d0fe4 | Michael Hanselmann | @classmethod
|
198 | ac2d0fe4 | Michael Hanselmann | def _BuildList(cls, cmd_result, fields_def, wanted_field_names, lvm_fields): |
199 | ac2d0fe4 | Michael Hanselmann | """Builds the final result list.
|
200 | ac2d0fe4 | Michael Hanselmann |
|
201 | ac2d0fe4 | Michael Hanselmann | @type cmd_result: iterable
|
202 | ac2d0fe4 | Michael Hanselmann | @param cmd_result: Iterable of LVM command output (iterable of lists)
|
203 | ac2d0fe4 | Michael Hanselmann | @type fields_def: list
|
204 | ac2d0fe4 | Michael Hanselmann | @param fields_def: Field definitions
|
205 | ac2d0fe4 | Michael Hanselmann | @type wanted_field_names: list
|
206 | ac2d0fe4 | Michael Hanselmann | @param wanted_field_names: List of requested fields
|
207 | ac2d0fe4 | Michael Hanselmann | @type lvm_fields: list
|
208 | ac2d0fe4 | Michael Hanselmann | @param lvm_fields: LVM fields
|
209 | ac2d0fe4 | Michael Hanselmann |
|
210 | ac2d0fe4 | Michael Hanselmann | """
|
211 | ac2d0fe4 | Michael Hanselmann | lvm_name_to_idx = dict([(lvm_name, idx)
|
212 | ac2d0fe4 | Michael Hanselmann | for (idx, lvm_name) in enumerate(lvm_fields)]) |
213 | ac2d0fe4 | Michael Hanselmann | field_to_idx = dict([(field_name, idx)
|
214 | ac2d0fe4 | Michael Hanselmann | for (idx, (field_name, _, _)) in enumerate(fields_def)]) |
215 | ac2d0fe4 | Michael Hanselmann | |
216 | ac2d0fe4 | Michael Hanselmann | data = [] |
217 | ac2d0fe4 | Michael Hanselmann | for raw_data in cmd_result: |
218 | ac2d0fe4 | Michael Hanselmann | row = [] |
219 | ac2d0fe4 | Michael Hanselmann | |
220 | ac2d0fe4 | Michael Hanselmann | for field_name in wanted_field_names: |
221 | ac2d0fe4 | Michael Hanselmann | (_, lvm_name, convert_fn) = fields_def[field_to_idx[field_name]] |
222 | ac2d0fe4 | Michael Hanselmann | |
223 | ac2d0fe4 | Michael Hanselmann | value = raw_data[lvm_name_to_idx[lvm_name]] |
224 | ac2d0fe4 | Michael Hanselmann | |
225 | ac2d0fe4 | Michael Hanselmann | if convert_fn:
|
226 | ac2d0fe4 | Michael Hanselmann | value = convert_fn(value) |
227 | ac2d0fe4 | Michael Hanselmann | |
228 | ac2d0fe4 | Michael Hanselmann | row.append(value) |
229 | ac2d0fe4 | Michael Hanselmann | |
230 | ac2d0fe4 | Michael Hanselmann | data.append(row) |
231 | ac2d0fe4 | Michael Hanselmann | |
232 | ac2d0fe4 | Michael Hanselmann | return data
|
233 | ac2d0fe4 | Michael Hanselmann | |
234 | ac2d0fe4 | Michael Hanselmann | @staticmethod
|
235 | ac2d0fe4 | Michael Hanselmann | def _BuildListCommand(cmd, sep, options, name): |
236 | ac2d0fe4 | Michael Hanselmann | """Builds LVM command line.
|
237 | ac2d0fe4 | Michael Hanselmann |
|
238 | ac2d0fe4 | Michael Hanselmann | @type cmd: string
|
239 | ac2d0fe4 | Michael Hanselmann | @param cmd: Command name
|
240 | ac2d0fe4 | Michael Hanselmann | @type sep: string
|
241 | ac2d0fe4 | Michael Hanselmann | @param sep: Field separator character
|
242 | ac2d0fe4 | Michael Hanselmann | @type options: list of strings
|
243 | ac2d0fe4 | Michael Hanselmann | @param options: Wanted LVM fields
|
244 | ac2d0fe4 | Michael Hanselmann | @type name: name or None
|
245 | ac2d0fe4 | Michael Hanselmann | @param name: Name of requested entity
|
246 | ac2d0fe4 | Michael Hanselmann |
|
247 | ac2d0fe4 | Michael Hanselmann | """
|
248 | ac2d0fe4 | Michael Hanselmann | args = [cmd, |
249 | ac2d0fe4 | Michael Hanselmann | "--noheadings", "--units=m", "--nosuffix", |
250 | ac2d0fe4 | Michael Hanselmann | "--separator", sep,
|
251 | ac2d0fe4 | Michael Hanselmann | "--options", ",".join(options)] |
252 | ac2d0fe4 | Michael Hanselmann | |
253 | ac2d0fe4 | Michael Hanselmann | if name is not None: |
254 | ac2d0fe4 | Michael Hanselmann | args.append(name) |
255 | ac2d0fe4 | Michael Hanselmann | |
256 | ac2d0fe4 | Michael Hanselmann | return args
|
257 | ac2d0fe4 | Michael Hanselmann | |
258 | ac2d0fe4 | Michael Hanselmann | @staticmethod
|
259 | ac2d0fe4 | Michael Hanselmann | def _RunListCommand(args): |
260 | ac2d0fe4 | Michael Hanselmann | """Run LVM command.
|
261 | ac2d0fe4 | Michael Hanselmann |
|
262 | ac2d0fe4 | Michael Hanselmann | """
|
263 | ac2d0fe4 | Michael Hanselmann | result = utils.RunCmd(args) |
264 | ac2d0fe4 | Michael Hanselmann | |
265 | ac2d0fe4 | Michael Hanselmann | if result.failed:
|
266 | ac2d0fe4 | Michael Hanselmann | raise errors.StorageError("Failed to run %r, command output: %s" % |
267 | ac2d0fe4 | Michael Hanselmann | (args[0], result.output))
|
268 | ac2d0fe4 | Michael Hanselmann | |
269 | ac2d0fe4 | Michael Hanselmann | return result.stdout
|
270 | ac2d0fe4 | Michael Hanselmann | |
271 | ac2d0fe4 | Michael Hanselmann | @staticmethod
|
272 | ac2d0fe4 | Michael Hanselmann | def _SplitList(data, sep, fieldcount): |
273 | ac2d0fe4 | Michael Hanselmann | """Splits LVM command output into rows and fields.
|
274 | ac2d0fe4 | Michael Hanselmann |
|
275 | ac2d0fe4 | Michael Hanselmann | @type data: string
|
276 | ac2d0fe4 | Michael Hanselmann | @param data: LVM command output
|
277 | ac2d0fe4 | Michael Hanselmann | @type sep: string
|
278 | ac2d0fe4 | Michael Hanselmann | @param sep: Field separator character
|
279 | ac2d0fe4 | Michael Hanselmann | @type fieldcount: int
|
280 | ac2d0fe4 | Michael Hanselmann | @param fieldcount: Expected number of fields
|
281 | ac2d0fe4 | Michael Hanselmann |
|
282 | ac2d0fe4 | Michael Hanselmann | """
|
283 | ac2d0fe4 | Michael Hanselmann | for line in data.splitlines(): |
284 | ac2d0fe4 | Michael Hanselmann | fields = line.strip().split(sep) |
285 | ac2d0fe4 | Michael Hanselmann | |
286 | ac2d0fe4 | Michael Hanselmann | if len(fields) != fieldcount: |
287 | ac2d0fe4 | Michael Hanselmann | continue
|
288 | ac2d0fe4 | Michael Hanselmann | |
289 | ac2d0fe4 | Michael Hanselmann | yield fields
|
290 | ac2d0fe4 | Michael Hanselmann | |
291 | ac2d0fe4 | Michael Hanselmann | |
292 | ac2d0fe4 | Michael Hanselmann | class LvmPvStorage(_LvmBase): |
293 | ac2d0fe4 | Michael Hanselmann | """LVM Physical Volume storage unit.
|
294 | ac2d0fe4 | Michael Hanselmann |
|
295 | ac2d0fe4 | Michael Hanselmann | """
|
296 | ac2d0fe4 | Michael Hanselmann | def _GetAllocatable(attr): |
297 | ac2d0fe4 | Michael Hanselmann | if attr:
|
298 | ac2d0fe4 | Michael Hanselmann | return (attr[0] == "a") |
299 | ac2d0fe4 | Michael Hanselmann | else:
|
300 | ac2d0fe4 | Michael Hanselmann | logging.warning("Invalid PV attribute: %r", attr)
|
301 | ac2d0fe4 | Michael Hanselmann | return False |
302 | ac2d0fe4 | Michael Hanselmann | |
303 | ac2d0fe4 | Michael Hanselmann | LIST_COMMAND = "pvs"
|
304 | 6032697c | Michael Hanselmann | |
305 | 6032697c | Michael Hanselmann | # Make sure to update constants.VALID_STORAGE_FIELDS when changing field
|
306 | 6032697c | Michael Hanselmann | # definitions.
|
307 | ac2d0fe4 | Michael Hanselmann | LIST_FIELDS = [ |
308 | 6032697c | Michael Hanselmann | (constants.SF_NAME, "pv_name", None), |
309 | 6032697c | Michael Hanselmann | (constants.SF_SIZE, "pv_size", _ParseSize),
|
310 | 6032697c | Michael Hanselmann | (constants.SF_USED, "pv_used", _ParseSize),
|
311 | 6032697c | Michael Hanselmann | (constants.SF_FREE, "pv_free", _ParseSize),
|
312 | 6032697c | Michael Hanselmann | (constants.SF_ALLOCATABLE, "pv_attr", _GetAllocatable),
|
313 | ac2d0fe4 | Michael Hanselmann | ] |
314 | ac2d0fe4 | Michael Hanselmann | |
315 | 9b648ee7 | Michael Hanselmann | def _SetAllocatable(self, name, allocatable): |
316 | 9b648ee7 | Michael Hanselmann | """Sets the "allocatable" flag on a physical volume.
|
317 | 9b648ee7 | Michael Hanselmann |
|
318 | 9b648ee7 | Michael Hanselmann | @type name: string
|
319 | 9b648ee7 | Michael Hanselmann | @param name: Physical volume name
|
320 | 9b648ee7 | Michael Hanselmann | @type allocatable: bool
|
321 | 9b648ee7 | Michael Hanselmann | @param allocatable: Whether to set the "allocatable" flag
|
322 | 9b648ee7 | Michael Hanselmann |
|
323 | 9b648ee7 | Michael Hanselmann | """
|
324 | 9b648ee7 | Michael Hanselmann | args = ["pvchange", "--allocatable"] |
325 | 9b648ee7 | Michael Hanselmann | |
326 | 9b648ee7 | Michael Hanselmann | if allocatable:
|
327 | 9b648ee7 | Michael Hanselmann | args.append("y")
|
328 | 9b648ee7 | Michael Hanselmann | else:
|
329 | 9b648ee7 | Michael Hanselmann | args.append("n")
|
330 | 9b648ee7 | Michael Hanselmann | |
331 | 9b648ee7 | Michael Hanselmann | args.append(name) |
332 | 9b648ee7 | Michael Hanselmann | |
333 | 9b648ee7 | Michael Hanselmann | result = utils.RunCmd(args) |
334 | 9b648ee7 | Michael Hanselmann | if result.failed:
|
335 | 9b648ee7 | Michael Hanselmann | raise errors.StorageError("Failed to modify physical volume," |
336 | 9b648ee7 | Michael Hanselmann | " pvchange output: %s" %
|
337 | 9b648ee7 | Michael Hanselmann | result.output) |
338 | 9b648ee7 | Michael Hanselmann | |
339 | 9b648ee7 | Michael Hanselmann | def Modify(self, name, changes): |
340 | 9b648ee7 | Michael Hanselmann | """Modifies flags on a physical volume.
|
341 | 9b648ee7 | Michael Hanselmann |
|
342 | 9b648ee7 | Michael Hanselmann | See L{_Base.Modify}.
|
343 | 9b648ee7 | Michael Hanselmann |
|
344 | 9b648ee7 | Michael Hanselmann | """
|
345 | 9b648ee7 | Michael Hanselmann | if constants.SF_ALLOCATABLE in changes: |
346 | 9b648ee7 | Michael Hanselmann | self._SetAllocatable(name, changes[constants.SF_ALLOCATABLE])
|
347 | 9b648ee7 | Michael Hanselmann | del changes[constants.SF_ALLOCATABLE]
|
348 | 9b648ee7 | Michael Hanselmann | |
349 | 9b648ee7 | Michael Hanselmann | # Other changes will be handled (and maybe refused) by the base class.
|
350 | 9b648ee7 | Michael Hanselmann | return _LvmBase.Modify(self, name, changes) |
351 | 9b648ee7 | Michael Hanselmann | |
352 | ac2d0fe4 | Michael Hanselmann | |
353 | ac2d0fe4 | Michael Hanselmann | class LvmVgStorage(_LvmBase): |
354 | ac2d0fe4 | Michael Hanselmann | """LVM Volume Group storage unit.
|
355 | ac2d0fe4 | Michael Hanselmann |
|
356 | ac2d0fe4 | Michael Hanselmann | """
|
357 | ac2d0fe4 | Michael Hanselmann | LIST_COMMAND = "vgs"
|
358 | 6032697c | Michael Hanselmann | |
359 | 6032697c | Michael Hanselmann | # Make sure to update constants.VALID_STORAGE_FIELDS when changing field
|
360 | 6032697c | Michael Hanselmann | # definitions.
|
361 | ac2d0fe4 | Michael Hanselmann | LIST_FIELDS = [ |
362 | 6032697c | Michael Hanselmann | (constants.SF_NAME, "vg_name", None), |
363 | 6032697c | Michael Hanselmann | (constants.SF_SIZE, "vg_size", _ParseSize),
|
364 | ac2d0fe4 | Michael Hanselmann | ] |
365 | ac2d0fe4 | Michael Hanselmann | |
366 | ac2d0fe4 | Michael Hanselmann | |
367 | ac2d0fe4 | Michael Hanselmann | # Lookup table for storage types
|
368 | ac2d0fe4 | Michael Hanselmann | _STORAGE_TYPES = { |
369 | ac2d0fe4 | Michael Hanselmann | constants.ST_FILE: FileStorage, |
370 | ac2d0fe4 | Michael Hanselmann | constants.ST_LVM_PV: LvmPvStorage, |
371 | ac2d0fe4 | Michael Hanselmann | constants.ST_LVM_VG: LvmVgStorage, |
372 | ac2d0fe4 | Michael Hanselmann | } |
373 | ac2d0fe4 | Michael Hanselmann | |
374 | ac2d0fe4 | Michael Hanselmann | |
375 | ac2d0fe4 | Michael Hanselmann | def GetStorageClass(name): |
376 | ac2d0fe4 | Michael Hanselmann | """Returns the class for a storage type.
|
377 | ac2d0fe4 | Michael Hanselmann |
|
378 | ac2d0fe4 | Michael Hanselmann | @type name: string
|
379 | ac2d0fe4 | Michael Hanselmann | @param name: Storage type
|
380 | ac2d0fe4 | Michael Hanselmann |
|
381 | ac2d0fe4 | Michael Hanselmann | """
|
382 | ac2d0fe4 | Michael Hanselmann | try:
|
383 | ac2d0fe4 | Michael Hanselmann | return _STORAGE_TYPES[name]
|
384 | ac2d0fe4 | Michael Hanselmann | except KeyError: |
385 | ac2d0fe4 | Michael Hanselmann | raise errors.StorageError("Unknown storage type: %r" % name) |
386 | ac2d0fe4 | Michael Hanselmann | |
387 | ac2d0fe4 | Michael Hanselmann | |
388 | ac2d0fe4 | Michael Hanselmann | def GetStorage(name, *args): |
389 | ac2d0fe4 | Michael Hanselmann | """Factory function for storage methods.
|
390 | ac2d0fe4 | Michael Hanselmann |
|
391 | ac2d0fe4 | Michael Hanselmann | @type name: string
|
392 | ac2d0fe4 | Michael Hanselmann | @param name: Storage type
|
393 | ac2d0fe4 | Michael Hanselmann |
|
394 | ac2d0fe4 | Michael Hanselmann | """
|
395 | ac2d0fe4 | Michael Hanselmann | return GetStorageClass(name)(*args) |