Statistics
| Branch: | Tag: | Revision:

root / lib / utils / storage.py @ d721894a

History | View | Annotate | Download (6.2 kB)

1
#
2
#
3

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

    
21
"""Utility functions for storage.
22

23
"""
24

    
25
import logging
26

    
27
from ganeti import constants
28
from ganeti import pathutils
29

    
30

    
31
def GetDiskTemplatesOfStorageType(storage_type):
32
  """Given the storage type, returns a list of disk templates based on that
33
     storage type."""
34
  return [dt for dt in constants.DISK_TEMPLATES
35
          if constants.DISK_TEMPLATES_STORAGE_TYPE[dt] == storage_type]
36

    
37

    
38
def GetLvmDiskTemplates():
39
  """Returns all disk templates that use LVM."""
40
  return GetDiskTemplatesOfStorageType(constants.ST_LVM_VG)
41

    
42

    
43
def IsDiskTemplateEnabled(disk_template, enabled_disk_templates):
44
  """Checks if a particular disk template is enabled.
45

46
  """
47
  return disk_template in enabled_disk_templates
48

    
49

    
50
def IsFileStorageEnabled(enabled_disk_templates):
51
  """Checks if file storage is enabled.
52

53
  """
54
  return IsDiskTemplateEnabled(constants.DT_FILE, enabled_disk_templates)
55

    
56

    
57
def IsSharedFileStorageEnabled(enabled_disk_templates):
58
  """Checks if shared file storage is enabled.
59

60
  """
61
  return IsDiskTemplateEnabled(constants.DT_SHARED_FILE, enabled_disk_templates)
62

    
63

    
64
def IsLvmEnabled(enabled_disk_templates):
65
  """Check whether or not any lvm-based disk templates are enabled."""
66
  return len(set(GetLvmDiskTemplates())
67
             .intersection(set(enabled_disk_templates))) != 0
68

    
69

    
70
def LvmGetsEnabled(enabled_disk_templates, new_enabled_disk_templates):
71
  """Checks whether lvm was not enabled before, but will be enabled after
72
     the operation.
73

74
  """
75
  if IsLvmEnabled(enabled_disk_templates):
76
    return False
77
  return set(GetLvmDiskTemplates()).intersection(
78
      set(new_enabled_disk_templates))
79

    
80

    
81
def _GetDefaultStorageUnitForDiskTemplate(cfg, disk_template):
82
  """Retrieves the identifier of the default storage entity for the given
83
  storage type.
84

85
  @type cfg: C{objects.ConfigData}
86
  @param cfg: the configuration data
87
  @type disk_template: string
88
  @param disk_template: a disk template, for example 'drbd'
89
  @rtype: string
90
  @return: identifier for a storage unit, for example the vg_name for lvm
91
     storage
92

93
  """
94
  storage_type = constants.DISK_TEMPLATES_STORAGE_TYPE[disk_template]
95
  cluster = cfg.GetClusterInfo()
96
  if disk_template in GetLvmDiskTemplates():
97
    return (storage_type, cfg.GetVGName())
98
  elif disk_template == constants.DT_FILE:
99
    return (storage_type, cluster.file_storage_dir)
100
  # FIXME: Adjust this, once SHARED_FILE_STORAGE_DIR
101
  # is not in autoconf anymore.
102
  elif disk_template == constants.DT_SHARED_FILE:
103
    return (storage_type, pathutils.DEFAULT_SHARED_FILE_STORAGE_DIR)
104
  else:
105
    return (storage_type, None)
106

    
107

    
108
def _GetDefaultStorageUnitForSpindles(cfg):
109
  """Creates a 'spindle' storage unit, by retrieving the volume group
110
  name and associating it to the lvm-pv storage type.
111

112
  @rtype: (string, string)
113
  @return: tuple (storage_type, storage_key), where storage type is
114
    'lvm-pv' and storage_key the name of the default volume group
115

116
  """
117
  return (constants.ST_LVM_PV, cfg.GetVGName())
118

    
119

    
120
# List of storage type for which space reporting is implemented.
121
# FIXME: Remove this, once the backend is capable to do this for all
122
# storage types.
123
_DISK_TEMPLATES_SPACE_QUERYABLE = GetLvmDiskTemplates() \
124
    + GetDiskTemplatesOfStorageType(constants.ST_FILE)
125

    
126

    
127
def GetStorageUnitsOfCluster(cfg, include_spindles=False):
128
  """Examines the cluster's configuration and returns a list of storage
129
  units and their storage keys, ordered by the order in which they
130
  are enabled.
131

132
  @type cfg: L{config.ConfigWriter}
133
  @param cfg: Cluster configuration
134
  @type include_spindles: boolean
135
  @param include_spindles: flag to include an extra storage unit for physical
136
    volumes
137
  @rtype: list of tuples (string, string)
138
  @return: list of storage units, each storage unit being a tuple of
139
    (storage_type, storage_key); storage_type is in
140
    C{constants.VALID_STORAGE_TYPES} and the storage_key a string to
141
    identify an entity of that storage type, for example a volume group
142
    name for LVM storage or a file for file storage.
143

144
  """
145
  cluster_config = cfg.GetClusterInfo()
146
  storage_units = []
147
  for disk_template in cluster_config.enabled_disk_templates:
148
    if disk_template in _DISK_TEMPLATES_SPACE_QUERYABLE:
149
      storage_units.append(
150
          _GetDefaultStorageUnitForDiskTemplate(cfg, disk_template))
151
  if include_spindles:
152
    included_storage_types = set([st for (st, _) in storage_units])
153
    if not constants.ST_LVM_PV in included_storage_types:
154
      storage_units.append(
155
          _GetDefaultStorageUnitForSpindles(cfg))
156

    
157
  return storage_units
158

    
159

    
160
def LookupSpaceInfoByStorageType(storage_space_info, storage_type):
161
  """Looks up the storage space info for a given storage type.
162

163
  Note that this lookup can be ambiguous if storage space reporting for several
164
  units of the same storage type was requested. This function is only supposed
165
  to be used for legacy code in situations where it actually is unambiguous.
166

167
  @type storage_space_info: list of dicts
168
  @param storage_space_info: result of C{GetNodeInfo}
169
  @type storage_type: string
170
  @param storage_type: a storage type, which is included in the storage_units
171
    list
172
  @rtype: tuple
173
  @return: returns the element of storage_space_info that matches the given
174
    storage type
175

176
  """
177
  result = None
178
  for unit_info in storage_space_info:
179
    if unit_info["type"] == storage_type:
180
      if result is None:
181
        result = unit_info
182
      else:
183
        # There is more than one storage type in the query, log a warning
184
        logging.warning("Storage space information requested for"
185
                        " ambiguous storage type '%s'.", storage_type)
186
  return result