Statistics
| Branch: | Tag: | Revision:

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)