Statistics
| Branch: | Tag: | Revision:

root / lib / utils / storage.py @ b669aa41

History | View | Annotate | Download (7.6 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

    
29

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

    
36

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

    
41

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

45
  """
46
  return disk_template in enabled_disk_templates
47

    
48

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

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

    
55

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

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

    
62

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

    
68

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

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

    
79

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

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

92
  """
93
  storage_type = constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]
94
  cluster = cfg.GetClusterInfo()
95
  if disk_template in GetLvmDiskTemplates():
96
    return (storage_type, cfg.GetVGName())
97
  elif disk_template == constants.DT_FILE:
98
    return (storage_type, cluster.file_storage_dir)
99
  elif disk_template == constants.DT_SHARED_FILE:
100
    return (storage_type, cluster.shared_file_storage_dir)
101
  else:
102
    return (storage_type, None)
103

    
104

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

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

113
  """
114
  return (constants.ST_LVM_PV, cfg.GetVGName())
115

    
116

    
117
def GetStorageUnitsOfCluster(cfg, include_spindles=False):
118
  """Examines the cluster's configuration and returns a list of storage
119
  units and their storage keys, ordered by the order in which they
120
  are enabled.
121

122
  @type cfg: L{config.ConfigWriter}
123
  @param cfg: Cluster configuration
124
  @type include_spindles: boolean
125
  @param include_spindles: flag to include an extra storage unit for physical
126
    volumes
127
  @rtype: list of tuples (string, string)
128
  @return: list of storage units, each storage unit being a tuple of
129
    (storage_type, storage_key); storage_type is in
130
    C{constants.STORAGE_TYPES} and the storage_key a string to
131
    identify an entity of that storage type, for example a volume group
132
    name for LVM storage or a file for file storage.
133

134
  """
135
  cluster_config = cfg.GetClusterInfo()
136
  storage_units = []
137
  for disk_template in cluster_config.enabled_disk_templates:
138
    if constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]\
139
        in constants.STS_REPORT:
140
      storage_units.append(
141
          _GetDefaultStorageUnitForDiskTemplate(cfg, disk_template))
142
  if include_spindles:
143
    included_storage_types = set([st for (st, _) in storage_units])
144
    if not constants.ST_LVM_PV in included_storage_types:
145
      storage_units.append(
146
          _GetDefaultStorageUnitForSpindles(cfg))
147

    
148
  return storage_units
149

    
150

    
151
def GetStorageUnits(cfg, disk_templates):
152
  """Get the cluster's storage units for the given disk templates.
153

154
  If any lvm-based disk template is requested, spindle information
155
  is added to the request.
156

157
  @type cfg: L{config.ConfigWriter}
158
  @param cfg: Cluster configuration
159
  @type disk_templates: list of string
160
  @param disk_templates: list of disk templates for which the storage
161
    units will be computed
162
  @rtype: list of tuples (string, string)
163
  @return: list of storage units, each storage unit being a tuple of
164
    (storage_type, storage_key); storage_type is in
165
    C{constants.STORAGE_TYPES} and the storage_key a string to
166
    identify an entity of that storage type, for example a volume group
167
    name for LVM storage or a file for file storage.
168

169
  """
170
  storage_units = []
171
  for disk_template in disk_templates:
172
    if constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]\
173
        in constants.STS_REPORT:
174
      storage_units.append(
175
          _GetDefaultStorageUnitForDiskTemplate(cfg, disk_template))
176
  if len(set(disk_templates) & constants.DTS_LVM) > 0:
177
    storage_units.append(
178
        _GetDefaultStorageUnitForSpindles(cfg))
179

    
180
  return storage_units
181

    
182

    
183
def LookupSpaceInfoByDiskTemplate(storage_space_info, disk_template):
184
  """Looks up the storage space info for a given disk template.
185

186
  @type storage_space_info: list of dicts
187
  @param storage_space_info: result of C{GetNodeInfo}
188
  @type disk_template: string
189
  @param disk_template: disk template to get storage space info
190
  @rtype: tuple
191
  @return: returns the element of storage_space_info that matches the given
192
    disk template
193

194
  """
195
  storage_type = constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]
196
  return LookupSpaceInfoByStorageType(storage_space_info, storage_type)
197

    
198

    
199
def LookupSpaceInfoByStorageType(storage_space_info, storage_type):
200
  """Looks up the storage space info for a given storage type.
201

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

206
  @type storage_space_info: list of dicts
207
  @param storage_space_info: result of C{GetNodeInfo}
208
  @type storage_type: string
209
  @param storage_type: a storage type, which is included in the storage_units
210
    list
211
  @rtype: tuple
212
  @return: returns the element of storage_space_info that matches the given
213
    storage type
214

215
  """
216
  result = None
217
  for unit_info in storage_space_info:
218
    if unit_info["type"] == storage_type:
219
      if result is None:
220
        result = unit_info
221
      else:
222
        # There is more than one storage type in the query, log a warning
223
        logging.warning("Storage space information requested for"
224
                        " ambiguous storage type '%s'.", storage_type)
225
  return result