Skip to content

Commit db943ee

Browse files
committed
Fix tuned profile to allow multiple settings
Signed-off-by: Kushal Deb <[email protected]>
1 parent c8e3946 commit db943ee

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

src/pybind/mgr/cephadm/inventory.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,9 @@ def add_setting(self, profile: str, setting: str, value: str) -> None:
637637
logger.error(
638638
f'Attempted to set setting "{setting}" for nonexistent os tuning profile "{profile}"')
639639

640+
def add_settings(self, profile: str, settings: dict) -> None:
641+
self.process_settings(profile, settings, action='add')
642+
640643
def rm_setting(self, profile: str, setting: str) -> None:
641644
if profile in self.profiles:
642645
if setting in self.profiles[profile].settings:
@@ -650,6 +653,39 @@ def rm_setting(self, profile: str, setting: str) -> None:
650653
logger.error(
651654
f'Attempted to remove setting "{setting}" from nonexistent os tuning profile "{profile}"')
652655

656+
def rm_settings(self, profile: str, settings: List[str]) -> None:
657+
self.process_settings(profile, settings, action='remove')
658+
659+
def process_settings(self, profile: str, settings: Union[dict, list], action: str) -> None:
660+
"""
661+
Process settings by either adding or removing them based on the action specified.
662+
"""
663+
if profile not in self.profiles:
664+
logger.error(f'Attempted to {action} settings for nonexistent os tuning profile "{profile}"')
665+
return
666+
profile_settings = self.profiles[profile].settings
667+
if action == 'remove' and isinstance(settings, list):
668+
invalid_settings = [s for s in settings if '=' in s or s not in profile_settings]
669+
if invalid_settings:
670+
raise OrchestratorError(
671+
f"Invalid settings: {', '.join(invalid_settings)}. "
672+
"Ensure settings are specified without '=' and exist in the profile. Correct format: key1,key2"
673+
)
674+
if action == 'add' and isinstance(settings, dict):
675+
for setting, value in settings.items():
676+
self.profiles[profile].settings[setting] = value
677+
elif action == 'remove' and isinstance(settings, list):
678+
for setting in settings:
679+
self.profiles[profile].settings.pop(setting, '')
680+
else:
681+
logger.error(
682+
f'Invalid action "{action}" for settings modification for tuned profile '
683+
f'"{profile}". Valid actions are "add" and "remove"'
684+
)
685+
return
686+
self.profiles[profile]._last_updated = datetime_to_str(datetime_now())
687+
self.save()
688+
653689
def add_profile(self, spec: TunedProfileSpec) -> None:
654690
spec._last_updated = datetime_to_str(datetime_now())
655691
self.profiles[spec.profile_name] = spec

src/pybind/mgr/cephadm/module.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3498,6 +3498,33 @@ def tuned_profile_add_setting(self, profile_name: str, setting: str, value: str)
34983498
self._kick_serve_loop()
34993499
return f'Added setting {setting} with value {value} to tuned profile {profile_name}'
35003500

3501+
@handle_orch_error
3502+
def tuned_profile_add_settings(self, profile_name: str, settings: dict) -> str:
3503+
if profile_name not in self.tuned_profiles:
3504+
raise OrchestratorError(
3505+
f"Tuned profile {profile_name} does not exist. Cannot add setting."
3506+
)
3507+
self.tuned_profiles.add_settings(profile_name, settings)
3508+
results = [
3509+
f"Added setting {key} with value {value} to tuned profile {profile_name}"
3510+
for key, value in settings.items()
3511+
]
3512+
self._kick_serve_loop()
3513+
return "\n".join(results)
3514+
3515+
@handle_orch_error
3516+
def tuned_profile_rm_settings(self, profile_name: str, settings: List[str]) -> str:
3517+
if profile_name not in self.tuned_profiles:
3518+
raise OrchestratorError(
3519+
f"Tuned profile {profile_name} does not exist. Cannot remove setting."
3520+
)
3521+
self.tuned_profiles.rm_settings(profile_name, settings)
3522+
results = [
3523+
f'Removed setting {settings} from tuned profile {profile_name}'
3524+
]
3525+
self._kick_serve_loop()
3526+
return "\n".join(results)
3527+
35013528
@handle_orch_error
35023529
def tuned_profile_rm_setting(self, profile_name: str, setting: str) -> str:
35033530
if profile_name not in self.tuned_profiles:

src/pybind/mgr/orchestrator/_interface.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,10 +901,18 @@ def tuned_profile_add_setting(self, profile_name: str, setting: str, value: str)
901901
"""Change/Add a specific setting for a tuned profile"""
902902
raise NotImplementedError()
903903

904+
def tuned_profile_add_settings(self, profile_name: str, setting: dict) -> OrchResult[str]:
905+
"""Change/Add multiple settings for a tuned profile"""
906+
raise NotImplementedError()
907+
904908
def tuned_profile_rm_setting(self, profile_name: str, setting: str) -> OrchResult[str]:
905909
"""Remove a specific setting for a tuned profile"""
906910
raise NotImplementedError()
907911

912+
def tuned_profile_rm_settings(self, profile_name: str, settings: List[str]) -> OrchResult[str]:
913+
"""Remove multiple settings from a tuned profile"""
914+
raise NotImplementedError
915+
908916
def upgrade_check(self, image: Optional[str], version: Optional[str]) -> OrchResult[str]:
909917
raise NotImplementedError()
910918

src/pybind/mgr/orchestrator/module.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,39 @@ def _tuned_profile_rm_setting(self, profile_name: str, setting: str) -> HandleCo
22502250
res = raise_if_exception(completion)
22512251
return HandleCommandResult(stdout=res)
22522252

2253+
@_cli_write_command("orch tuned-profile add-settings")
2254+
def _tuned_profile_add_settings(self, profile_name: str, settings: str) -> HandleCommandResult:
2255+
try:
2256+
setting_pairs = settings.split(",")
2257+
parsed_setting = {}
2258+
parsed_setting = {key.strip(): value.strip() for key, value in (s.split('=', 1) for s in setting_pairs)}
2259+
completion = self.tuned_profile_add_settings(profile_name, parsed_setting)
2260+
res = raise_if_exception(completion)
2261+
return HandleCommandResult(stdout=res)
2262+
except ValueError:
2263+
error_message = (
2264+
"Error: Invalid format detected. "
2265+
"The correct format is key=value pairs separated by commas,"
2266+
"e.g., 'vm.swappiness=11,vm.user_reserve_kbytes=116851'"
2267+
)
2268+
return HandleCommandResult(stderr=error_message)
2269+
2270+
@_cli_write_command("orch tuned-profile rm-settings")
2271+
def _tuned_profile_rm_settings(self, profile_name: str, settings: str) -> HandleCommandResult:
2272+
try:
2273+
setting = [s.strip() for s in settings.split(",") if s.strip()]
2274+
if not setting:
2275+
raise ValueError(
2276+
"Error: Invalid format."
2277+
"The correct format is key1,key2"
2278+
"e.g., vm.swappiness,vm.user_reserve_kbytes"
2279+
)
2280+
completion = self.tuned_profile_rm_settings(profile_name, setting)
2281+
res = raise_if_exception(completion)
2282+
return HandleCommandResult(stdout=res)
2283+
except ValueError as e:
2284+
return HandleCommandResult(stderr=str(e))
2285+
22532286
def self_test(self) -> None:
22542287
old_orch = self._select_orchestrator()
22552288
self._set_backend('')

0 commit comments

Comments
 (0)