From 53461364da022e839f832dcbe4610a5b6a2787b5 Mon Sep 17 00:00:00 2001 From: Patrick Seidensal Date: Tue, 16 Mar 2021 17:01:48 +0100 Subject: [PATCH] mgr/cephadm: fix issue with missing prometheus alerts Files passed as configuration to the cephadm binary had not been created and mapped to the container, if those files weren't included in the required files section inside cephadm. This prevented optional file includes in the configuration. The configuration file for the Prometheus default alerts is not mandatory and hence wasn't included in the required files section, still it needs to be added to the container by cephadm. This change enables optional files to be included in the configuration for monitoring components, so that those files are created and mapped within the container. Note that a `required_files` variable has been removed at one position in these changes, though it wasn't used to ensure that required files were included in the configuration at that point anyway. The test which ensures that all required files are passed is somewhere else. Fixes: https://tracker.ceph.com/issues/49856 Conflicts: src/cephadm/cephadm src/cephadm/tests/test_cephadm.py Signed-off-by: Patrick Seidensal (cherry picked from commit 38f9846d13ae2c5f12bde3397d2826b1cf43759b) (cherry picked from commit aacd8d195c1a202a54a7c12b2d0239d5b3e828b3) --- src/cephadm/cephadm | 11 ++++--- src/cephadm/tests/test_cephadm.py | 48 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/cephadm/cephadm b/src/cephadm/cephadm index 8e99357557d93..662b758d4127c 100755 --- a/src/cephadm/cephadm +++ b/src/cephadm/cephadm @@ -1824,7 +1824,6 @@ def create_daemon_dirs(fsid, daemon_type, daemon_id, uid, gid, if daemon_type in Monitoring.components.keys(): config_json: Dict[str, Any] = get_parm(args.config_json) - required_files = Monitoring.components[daemon_type].get('config-json-files', list()) # Set up directories specific to the monitoring component config_dir = '' @@ -1848,10 +1847,14 @@ def create_daemon_dirs(fsid, daemon_type, daemon_id, uid, gid, makedirs(os.path.join(data_dir_root, config_dir, 'data'), uid, gid, 0o755) # populate the config directory for the component from the config-json - for fname in required_files: - if 'files' in config_json: # type: ignore + if 'files' in config_json: + for fname in config_json['files']: content = dict_get_join(config_json['files'], fname) - with open(os.path.join(data_dir_root, config_dir, fname), 'w') as f: + if os.path.isabs(fname): + fpath = os.path.join(data_dir_root, fname.lstrip(os.path.sep)) + else: + fpath = os.path.join(data_dir_root, config_dir, fname) + with open(fpath, 'w') as f: os.fchown(f.fileno(), uid, gid) os.fchmod(f.fileno(), 0o600) f.write(content) diff --git a/src/cephadm/tests/test_cephadm.py b/src/cephadm/tests/test_cephadm.py index e0d51f2c45e6d..e5787fe50062a 100644 --- a/src/cephadm/tests/test_cephadm.py +++ b/src/cephadm/tests/test_cephadm.py @@ -507,3 +507,51 @@ class TestMonitoring(object): _call.return_value = '', '{}, version 0.16.1'.format(daemon_type.replace('-', '_')), 0 version = cd.Monitoring.get_version(ctx, 'container_id', daemon_type) assert version == '0.16.1' + + @mock.patch('cephadm.os.fchown') + @mock.patch('cephadm.get_parm') + @mock.patch('cephadm.makedirs') + @mock.patch('cephadm.open') + @mock.patch('cephadm.make_log_dir') + @mock.patch('cephadm.make_data_dir') + @mock.patch('cephadm.args') + def test_create_daemon_dirs_prometheus(self, args, make_data_dir, make_log_dir, _open, makedirs, + get_parm, fchown): + """ + Ensures the required and optional files given in the configuration are + created and mapped correctly inside the container. Tests absolute and + relative file paths given in the configuration. + """ + args.data_dir = '/somedir' + fsid = 'aaf5a720-13fe-4a3b-82b9-2d99b7fd9704' + daemon_type = 'prometheus' + uid, gid = 50, 50 + daemon_id = 'home' + files = { + 'files': { + 'prometheus.yml': 'foo', + '/etc/prometheus/alerting/ceph_alerts.yml': 'bar' + } + } + get_parm.return_value = files + + cd.create_daemon_dirs(fsid, + daemon_type, + daemon_id, + uid, + gid, + config=None, + keyring=None) + + prefix = '{data_dir}/{fsid}/{daemon_type}.{daemon_id}'.format( + data_dir=args.data_dir, + fsid=fsid, + daemon_type=daemon_type, + daemon_id=daemon_id + ) + assert _open.call_args_list == [ + call('{}/etc/prometheus/prometheus.yml'.format(prefix), 'w'), + call('{}/etc/prometheus/alerting/ceph_alerts.yml'.format(prefix), 'w'), + ] + assert call().__enter__().write('foo') in _open.mock_calls + assert call().__enter__().write('bar') in _open.mock_calls -- 2.39.5