3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 from cmdatahandlers.api import configerror
16 from cmdatahandlers.api import config
17 from cmdatahandlers.api import utils
20 BARE_LVM_MOUNT_DIR = "/var/lib/docker"
21 BARE_LVM_MOUNT_OPT = "noatime,nodiratime,logbufs=8,pquota"
24 class Config(config.Config):
25 def __init__(self, confman):
26 super(Config, self).__init__(confman)
27 self.ROOT = 'cloud.storage_profiles'
28 self.DOMAIN = 'storage_profiles'
35 self._validate_storage_profiles()
37 def _validate_storage_profiles(self):
38 profiles = self.get_storage_profiles()
39 utils.validate_list_items_unique(profiles)
40 for profile in profiles:
41 self._validate_storage_profile(profile)
43 def _validate_storage_profile(self, profile):
44 backend = self.get_profile_backend(profile)
45 storageconf = self.confman.get_storage_config_handler()
46 backends = storageconf.get_storage_backends()
47 if backend not in backends:
48 raise configerror.ConfigError(
49 'Invalid backend %s provided in profile %s' % (backend, profile))
51 self.get_profile_nr_of_ceph_osd_disks(profile)
52 elif backend == 'lvm':
53 self.get_profile_lvm_cinder_storage_partitions(profile)
54 self.get_profile_lvm_instance_storage_partitions(profile)
55 self.get_profile_lvm_instance_cow_lv_storage_percentage(profile)
56 self.get_profile_instance_storage_percentage(profile)
58 def is_valid_profile(self, profile):
60 profiles = self.get_storage_profiles()
61 if profile not in profiles:
62 raise configerror.ConfigError('Invalid profile name %s' % profile)
64 def get_storage_profiles(self):
65 """ get the storage profiles list
69 A list of storage profile(s) names
73 ConfigError in-case of an error
75 return self.config[self.ROOT].keys()
77 def get_profile_ceph_osd_disks(self, profile):
78 """ get the ceph osd disks
90 ConfigError in-case of an error
92 return self._get_attribute(profile, 'ceph_osd_disks')
94 def get_profile_ceph_osd_journal_disk(self, profile):
95 """ get the ceph osd journal disk
103 The ceph osd journal disk
107 ConfigError in-case of an error
109 return self._get_attribute(profile, 'ceph_osd_journal_disk')
111 def get_profile_ceph_openstack_pg_proportion(self, profile):
112 openstack_pg_ratio, caas_pg_ratio = self._get_ceph_pg_share_ratios(profile)
113 return openstack_pg_ratio / (openstack_pg_ratio + caas_pg_ratio)
115 def _get_ceph_pg_share_ratios(self, profile):
116 pg_share_ratios = self.get_profile_ceph_openstack_caas_pg_ratio(profile).split(':')
117 return map(lambda r: float(r), pg_share_ratios)
119 def get_profile_ceph_caas_pg_proportion(self, profile):
120 openstack_pg_ratio, caas_pg_ratio = self._get_ceph_pg_share_ratios(profile)
121 return caas_pg_ratio / (openstack_pg_ratio + caas_pg_ratio)
123 def get_profile_ceph_openstack_caas_pg_ratio(self, profile):
124 """ get the ceph openstack-caas pg share ratio
132 The ceph osd share ratio
136 ConfigError in-case of an error
138 return self._get_optional_attribute(
139 profile, 'ceph_pg_openstack_caas_share_ratio', "1:0")
141 def get_profile_nr_of_ceph_osd_disks(self, profile):
142 """ get the number of ceph osd disks
150 The number of ceph osd disks
154 ConfigError in-case of an error
157 self.is_valid_profile(profile)
159 if 'nr_of_ceph_osd_disks' not in self.config[self.ROOT][profile]:
160 ceph_osd_disks = self._get_attribute(profile, 'ceph_osd_disks')
161 return len(ceph_osd_disks)
162 return self.config[self.ROOT][profile]['nr_of_ceph_osd_disks']
164 def get_profile_lvm_cinder_storage_partitions(self, profile):
165 """ get the lvm_cinder_storage_partitions
173 The lvm_cinder_storage_partitions
177 ConfigError in-case of an error
179 return self._get_attribute(profile, 'lvm_cinder_storage_partitions')
181 def get_profile_backend(self, profile):
182 """ get the storage profile backend
194 ConfigError in-case of an error
196 return self._get_attribute(profile, 'backend')
198 def get_profile_lvm_instance_storage_partitions(self, profile):
199 """ get the lvm_instance_storage_partitions
207 The lvm_instance_storage_partitions
211 ConfigError in-case of an error
213 return self._get_attribute(profile, 'lvm_instance_storage_partitions')
215 def get_profile_lvm_instance_cow_lv_storage_percentage(self, profile):
216 """ get the lvm_instance_cow_lv_storage_percentage
224 The lvm_instance_cow_lv_storage_percentage
228 ConfigError in-case of an error
230 return self._get_attribute(profile, 'lvm_instance_cow_lv_storage_percentage')
232 def get_profile_instance_storage_percentage(self, profile):
233 """ get the instance_storage_percentage
241 The instance_storage_percentage
245 ConfigError in-case of an error
247 return self._get_attribute(profile, 'instance_storage_percentage')
249 def get_profile_bare_lvm_mount_options(self, profile):
250 """ get the mount_options
262 ConfigError in-case of an error
264 return BARE_LVM_MOUNT_OPT
266 def get_profile_bare_lvm_mount_dir(self, profile):
267 """ get the mount_dir
279 ConfigError in-case of an error
281 return BARE_LVM_MOUNT_DIR
283 def get_profile_bare_lvm_lv_name(self, profile):
296 ConfigError in-case of an error
298 return self._get_attribute(profile, 'lv_name')
300 def _get_attribute(self, profile, attribute):
301 """ get arbirary storage profile attribute
314 ConfigError in-case of an error
317 self.is_valid_profile(profile)
318 if attribute not in self.config[self.ROOT][profile]:
319 raise configerror.ConfigError(
320 'Profile %s does not have %s configured' % (attribute, profile))
321 return self.config[self.ROOT][profile][attribute]
323 def _get_optional_attribute(self, profile, attribute, default_value=""):
324 """ get arbirary optional storage profile attribute
337 ConfigError in-case of an error
340 self.is_valid_profile(profile)
341 if attribute not in self.config[self.ROOT][profile]:
343 return self.config[self.ROOT][profile][attribute]