]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/cephadm/tuned_profiles.py
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / pybind / mgr / cephadm / tuned_profiles.py
CommitLineData
2a845540
TL
1import logging
2from typing import Dict, List, TYPE_CHECKING
3from ceph.utils import datetime_now
4from .schedule import HostAssignment
5from ceph.deployment.service_spec import ServiceSpec, TunedProfileSpec
6
7if TYPE_CHECKING:
8 from cephadm.module import CephadmOrchestrator
9
10logger = logging.getLogger(__name__)
11
12SYSCTL_DIR = '/etc/sysctl.d'
13
14
15class TunedProfileUtils():
16 def __init__(self, mgr: "CephadmOrchestrator") -> None:
17 self.mgr = mgr
18
19 def _profile_to_str(self, p: TunedProfileSpec) -> str:
20 p_str = f'# created by cephadm\n# tuned profile "{p.profile_name}"\n\n'
21 for k, v in p.settings.items():
22 p_str += f'{k} = {v}\n'
23 return p_str
24
25 def _write_all_tuned_profiles(self) -> None:
26 host_profile_mapping: Dict[str, List[Dict[str, str]]] = {}
27 for host in self.mgr.cache.get_hosts():
28 host_profile_mapping[host] = []
29
30 for profile in self.mgr.tuned_profiles.list_profiles():
31 p_str = self._profile_to_str(profile)
32 ha = HostAssignment(
33 spec=ServiceSpec(
34 'crash', placement=profile.placement),
35 hosts=self.mgr.cache.get_schedulable_hosts(),
36 unreachable_hosts=self.mgr.cache.get_unreachable_hosts(),
37 draining_hosts=self.mgr.cache.get_draining_hosts(),
38 daemons=[],
39 networks=self.mgr.cache.networks,
40 )
41 all_slots, _, _ = ha.place()
42 for host in {s.hostname for s in all_slots}:
43 host_profile_mapping[host].append({profile.profile_name: p_str})
44
45 for host, profiles in host_profile_mapping.items():
46 self._remove_stray_tuned_profiles(host, profiles)
47 self._write_tuned_profiles(host, profiles)
48
49 def _remove_stray_tuned_profiles(self, host: str, profiles: List[Dict[str, str]]) -> None:
39ae355f
TL
50 """
51 this function looks at the contents of /etc/sysctl.d/ for profiles we have written
52 that should now be removed. It assumes any file with "-cephadm-tuned-profile.conf" in
53 it is written by us any without that are not. Only files written by us are considered
54 candidates for removal. The "profiles" parameter is a list of dictionaries that map
55 profile names to the file contents to actually be written to the
56 /etc/sysctl.d/<profile-name>-cephadm-tuned-profile.conf. For example
57 [
58 {
59 'profile1': 'setting1: value1\nsetting2: value2'
60 },
61 {
62 'profile2': 'setting3: value3'
63 }
64 ]
65 what we want to end up doing is going through the keys of the dicts and appending
66 -cephadm-tuned-profile.conf to the profile names to build our list of profile files that
67 SHOULD be on the host. Then if we see any file names that don't match this, but
68 DO include "-cephadm-tuned-profile.conf" (implying they're from us), remove them.
69 """
aee94f69 70 if self.mgr.cache.is_host_unreachable(host):
2a845540
TL
71 return
72 cmd = ['ls', SYSCTL_DIR]
39ae355f 73 found_files = self.mgr.ssh.check_execute_command(host, cmd, log_command=self.mgr.log_refresh_metadata).split('\n')
2a845540 74 found_files = [s.strip() for s in found_files]
39ae355f
TL
75 profile_names: List[str] = sum([[*p] for p in profiles], []) # extract all profiles names
76 profile_names = list(set(profile_names)) # remove duplicates
77 expected_files = [p + '-cephadm-tuned-profile.conf' for p in profile_names]
2a845540
TL
78 updated = False
79 for file in found_files:
80 if '-cephadm-tuned-profile.conf' not in file:
81 continue
39ae355f 82 if file not in expected_files:
2a845540
TL
83 logger.info(f'Removing stray tuned profile file {file}')
84 cmd = ['rm', '-f', f'{SYSCTL_DIR}/{file}']
85 self.mgr.ssh.check_execute_command(host, cmd)
86 updated = True
87 if updated:
88 self.mgr.ssh.check_execute_command(host, ['sysctl', '--system'])
89
90 def _write_tuned_profiles(self, host: str, profiles: List[Dict[str, str]]) -> None:
aee94f69 91 if self.mgr.cache.is_host_unreachable(host):
2a845540
TL
92 return
93 updated = False
94 for p in profiles:
95 for profile_name, content in p.items():
96 if self.mgr.cache.host_needs_tuned_profile_update(host, profile_name):
97 logger.info(f'Writing tuned profile {profile_name} to host {host}')
98 profile_filename: str = f'{SYSCTL_DIR}/{profile_name}-cephadm-tuned-profile.conf'
99 self.mgr.ssh.write_remote_file(host, profile_filename, content.encode('utf-8'))
100 updated = True
101 if updated:
102 self.mgr.ssh.check_execute_command(host, ['sysctl', '--system'])
103 self.mgr.cache.last_tuned_profile_update[host] = datetime_now()