logger.error(
f'Attempted to set setting "{setting}" for nonexistent os tuning profile "{profile}"')
+ def add_settings(self, profile: str, settings: dict) -> None:
+ self.process_settings(profile, settings, action='add')
+
def rm_setting(self, profile: str, setting: str) -> None:
if profile in self.profiles:
if setting in self.profiles[profile].settings:
logger.error(
f'Attempted to remove setting "{setting}" from nonexistent os tuning profile "{profile}"')
+ def rm_settings(self, profile: str, settings: List[str]) -> None:
+ self.process_settings(profile, settings, action='remove')
+
+ def process_settings(self, profile: str, settings: Union[dict, list], action: str) -> None:
+ """
+ Process settings by either adding or removing them based on the action specified.
+ """
+ if profile not in self.profiles:
+ logger.error(f'Attempted to {action} settings for nonexistent os tuning profile "{profile}"')
+ return
+ profile_settings = self.profiles[profile].settings
+ if action == 'remove' and isinstance(settings, list):
+ invalid_settings = [s for s in settings if '=' in s or s not in profile_settings]
+ if invalid_settings:
+ raise OrchestratorError(
+ f"Invalid settings: {', '.join(invalid_settings)}. "
+ "Ensure settings are specified without '=' and exist in the profile. Correct format: key1,key2"
+ )
+ if action == 'add' and isinstance(settings, dict):
+ for setting, value in settings.items():
+ self.profiles[profile].settings[setting] = value
+ elif action == 'remove' and isinstance(settings, list):
+ for setting in settings:
+ self.profiles[profile].settings.pop(setting, '')
+ else:
+ logger.error(
+ f'Invalid action "{action}" for settings modification for tuned profile '
+ f'"{profile}". Valid actions are "add" and "remove"'
+ )
+ return
+ self.profiles[profile]._last_updated = datetime_to_str(datetime_now())
+ self.save()
+
def add_profile(self, spec: TunedProfileSpec) -> None:
spec._last_updated = datetime_to_str(datetime_now())
self.profiles[spec.profile_name] = spec
self._kick_serve_loop()
return f'Added setting {setting} with value {value} to tuned profile {profile_name}'
+ @handle_orch_error
+ def tuned_profile_add_settings(self, profile_name: str, settings: dict) -> str:
+ if profile_name not in self.tuned_profiles:
+ raise OrchestratorError(
+ f"Tuned profile {profile_name} does not exist. Cannot add setting."
+ )
+ self.tuned_profiles.add_settings(profile_name, settings)
+ results = [
+ f"Added setting {key} with value {value} to tuned profile {profile_name}"
+ for key, value in settings.items()
+ ]
+ self._kick_serve_loop()
+ return "\n".join(results)
+
+ @handle_orch_error
+ def tuned_profile_rm_settings(self, profile_name: str, settings: List[str]) -> str:
+ if profile_name not in self.tuned_profiles:
+ raise OrchestratorError(
+ f"Tuned profile {profile_name} does not exist. Cannot remove setting."
+ )
+ self.tuned_profiles.rm_settings(profile_name, settings)
+ results = [
+ f'Removed setting {settings} from tuned profile {profile_name}'
+ ]
+ self._kick_serve_loop()
+ return "\n".join(results)
+
@handle_orch_error
def tuned_profile_rm_setting(self, profile_name: str, setting: str) -> str:
if profile_name not in self.tuned_profiles:
"""Change/Add a specific setting for a tuned profile"""
raise NotImplementedError()
+ def tuned_profile_add_settings(self, profile_name: str, setting: dict) -> OrchResult[str]:
+ """Change/Add multiple settings for a tuned profile"""
+ raise NotImplementedError()
+
def tuned_profile_rm_setting(self, profile_name: str, setting: str) -> OrchResult[str]:
"""Remove a specific setting for a tuned profile"""
raise NotImplementedError()
+ def tuned_profile_rm_settings(self, profile_name: str, settings: List[str]) -> OrchResult[str]:
+ """Remove multiple settings from a tuned profile"""
+ raise NotImplementedError
+
def upgrade_check(self, image: Optional[str], version: Optional[str]) -> OrchResult[str]:
raise NotImplementedError()
res = raise_if_exception(completion)
return HandleCommandResult(stdout=res)
+ @_cli_write_command("orch tuned-profile add-settings")
+ def _tuned_profile_add_settings(self, profile_name: str, settings: str) -> HandleCommandResult:
+ try:
+ setting_pairs = settings.split(",")
+ parsed_setting = {}
+ parsed_setting = {key.strip(): value.strip() for key, value in (s.split('=', 1) for s in setting_pairs)}
+ completion = self.tuned_profile_add_settings(profile_name, parsed_setting)
+ res = raise_if_exception(completion)
+ return HandleCommandResult(stdout=res)
+ except ValueError:
+ error_message = (
+ "Error: Invalid format detected. "
+ "The correct format is key=value pairs separated by commas,"
+ "e.g., 'vm.swappiness=11,vm.user_reserve_kbytes=116851'"
+ )
+ return HandleCommandResult(stderr=error_message)
+
+ @_cli_write_command("orch tuned-profile rm-settings")
+ def _tuned_profile_rm_settings(self, profile_name: str, settings: str) -> HandleCommandResult:
+ try:
+ setting = [s.strip() for s in settings.split(",") if s.strip()]
+ if not setting:
+ raise ValueError(
+ "Error: Invalid format."
+ "The correct format is key1,key2"
+ "e.g., vm.swappiness,vm.user_reserve_kbytes"
+ )
+ completion = self.tuned_profile_rm_settings(profile_name, setting)
+ res = raise_if_exception(completion)
+ return HandleCommandResult(stdout=res)
+ except ValueError as e:
+ return HandleCommandResult(stderr=str(e))
+
def self_test(self) -> None:
old_orch = self._select_orchestrator()
self._set_backend('')