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 class Config(config.Config):
22 DEFAULT_HUGEPAGESZ = 'default_hugepagesz'
23 HUGEPAGESZ = 'hugepagesz'
24 HUGEPAGES = 'hugepages'
25 PLATFORM_CPUS = 'platform_cpus'
26 OVS_DPDK_CPUS = 'ovs_dpdk_cpus'
27 PROFILE_OPTIONS = {DEFAULT_HUGEPAGESZ: 'get_profile_default_hugepage_size',
28 HUGEPAGESZ: 'get_profile_hugepage_size',
29 HUGEPAGES: 'get_profile_hugepage_count',
30 PLATFORM_CPUS: 'get_platform_cpus',
31 OVS_DPDK_CPUS: 'get_ovs_dpdk_cpus'}
33 ERR_INVALID_PROFILE = 'Invalid profile name {}'
34 ERR_MISSING_PROFILE_KEY = 'Profile {} does not have %s'
35 ERR_MISSING_DEFAULT_HUGEPAGESZ = ERR_MISSING_PROFILE_KEY % DEFAULT_HUGEPAGESZ
36 ERR_MISSING_HUGEPAGESZ = ERR_MISSING_PROFILE_KEY % HUGEPAGESZ
37 ERR_MISSING_HUGEPAGES = ERR_MISSING_PROFILE_KEY % HUGEPAGES
38 ERR_MISSING_PLATFORM_CPUS = ERR_MISSING_PROFILE_KEY % PLATFORM_CPUS
39 ERR_MISSING_OVS_DPDK_CPUS = ERR_MISSING_PROFILE_KEY % OVS_DPDK_CPUS
42 def raise_error(context, err_type):
43 raise configerror.ConfigError(err_type.format(context))
45 def __init__(self, confman):
46 super(Config, self).__init__(confman)
47 self.ROOT = 'cloud.performance_profiles'
48 self.DOMAIN = 'performance_profiles'
55 self._validate_performance_profiles()
57 def _validate_performance_profiles(self):
58 profiles = self.get_performance_profiles()
59 utils.validate_list_items_unique(profiles)
60 for profile in profiles:
61 self._validate_performance_profile(profile)
63 def _validate_performance_profile(self, profile):
64 self.get_profile_default_hugepage_size(profile)
65 self.get_profile_hugepage_size(profile)
66 self.get_profile_hugepage_count(profile)
67 self.get_platform_cpus(profile)
68 self.get_ovs_dpdk_cpus(profile)
70 def is_valid_profile(self, profile):
71 profiles = self.get_performance_profiles()
72 if profile not in profiles:
73 self.raise_error(profile, self.ERR_INVALID_PROFILE)
75 def get_performance_profiles(self):
76 """ get the performance profiles list
80 A list of performance profile(s) names
84 ConfigError in-case of an error
87 return self.config[self.ROOT].keys()
89 # pylint: disable=invalid-name
90 def get_profile_default_hugepage_size(self, profile):
91 """ get the default hugepage size
99 The default hugepage size
103 ConfigError in-case of an error
105 self.is_valid_profile(profile)
107 if self.DEFAULT_HUGEPAGESZ not in self.config[self.ROOT][profile]:
108 self.raise_error(profile, self.ERR_MISSING_DEFAULT_HUGEPAGESZ)
110 return self.config[self.ROOT][profile][self.DEFAULT_HUGEPAGESZ]
112 def get_profile_hugepage_size(self, profile):
113 """ get the hugepage size
125 ConfigError in-case of an error
127 self.is_valid_profile(profile)
129 if self.HUGEPAGESZ not in self.config[self.ROOT][profile]:
130 self.raise_error(profile, self.ERR_MISSING_HUGEPAGESZ)
132 return self.config[self.ROOT][profile][self.HUGEPAGESZ]
134 def get_profile_hugepage_count(self, profile):
135 """ get the hugepage count
147 ConfigError in-case of an error
149 self.is_valid_profile(profile)
151 if self.HUGEPAGES not in self.config[self.ROOT][profile]:
152 self.raise_error(profile, self.ERR_MISSING_HUGEPAGES)
154 return self.config[self.ROOT][profile][self.HUGEPAGES]
156 def get_platform_cpus(self, profile):
157 """ get the Platforma CPUs (isolate CPUs from the general scheduler).
165 The platform CPUs dictionary
169 ConfigError in-case of an error
171 self.is_valid_profile(profile)
173 if self.PLATFORM_CPUS not in self.config[self.ROOT][profile]:
174 self.raise_error(profile, self.ERR_MISSING_PLATFORM_CPUS)
176 return self.config[self.ROOT][profile][self.PLATFORM_CPUS]
178 def get_ovs_dpdk_cpus(self, profile):
179 """ get the ovs-dpdk cpu(s)
187 The ovs-dpdk dedicated cpu(s) string
191 ConfigError in-case of an error
193 self.is_valid_profile(profile)
195 if self.OVS_DPDK_CPUS not in self.config[self.ROOT][profile]:
196 self.raise_error(profile, self.ERR_MISSING_OVS_DPDK_CPUS)
198 return self.config[self.ROOT][profile][self.OVS_DPDK_CPUS]
201 """ Dump all performaceprofiles data. """
204 return self.config[self.ROOT]
206 def _fill_option_value(self, profile_data, profile, option, value):
209 value = getattr(self, self.PROFILE_OPTIONS[option])(profile)
210 except configerror.ConfigError:
212 profile_data.update({option:value})
214 # pylint: disable=too-many-arguments
215 def update(self, name, platform_cpus=None, ovs_dpdk_cpus=None, hugepages=None,
216 default_hugepagesz=None, hugepagesz=None):
217 """ Update performance profile, overwriting existing profile.
223 platform_cpus : dict, optional
225 The syntax is: {'numa0': <int>, 'numa1': <int>, ..., 'numaN': <int>}
226 ovs_dpdk_cpus : dict, optional
227 OVS-DPDK dedicated cores.
228 The syntax is the same as platform_cpus.
229 hugepages : int, optional
230 The number of allocated persistent huge pages.
231 default_hugepagesz : str, optional
232 Default huge page size (the default value is '1G').
233 Valid values are '2M' and '1G'
234 hugepagesz : str, optional
235 Huge page size (the default value is '1G').
236 Valid values are '2M' and '1G'
240 self._fill_option_value(data, name, 'platform_cpus', platform_cpus)
241 self._fill_option_value(data, name, 'ovs_dpdk_cpus', ovs_dpdk_cpus)
242 self._fill_option_value(data, name, 'hugepages', hugepages)
243 self._fill_option_value(data, name, 'default_hugepagesz', default_hugepagesz)
244 self._fill_option_value(data, name, 'hugepagesz', hugepagesz)
245 self.config[self.ROOT].update({name:data})
247 def delete(self, name):
257 Raises ConfigError if profile does not exist.
260 self.config[self.ROOT].pop(name)
262 self.raise_error(name, self.ERR_INVALID_PROFILE)