Skip to content

Commit 0787262

Browse files
authored
Merge pull request ceph#53910 from rkachach/fix_issue_63123
mgr/rook: fixing rook-ceph-exporter daemon type handling Reviewed-by: Juan Miguel Olmo Martínez <[email protected]> Reviewed-by: travisn <[email protected]>
2 parents 38a6007 + 15cebf2 commit 0787262

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

src/pybind/mgr/rook/module.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,17 @@ def _list_daemons(self,
457457
for p in pods:
458458
sd = orchestrator.DaemonDescription()
459459
sd.hostname = p['hostname']
460-
sd.daemon_type = p['labels']['app'].replace('rook-ceph-', '')
460+
461+
# In Rook environments, the 'ceph-exporter' daemon is named 'exporter' whereas
462+
# in the orchestrator interface, it is named 'ceph-exporter'. The purpose of the
463+
# following adjustment is to ensure that the 'daemon_type' is correctly set.
464+
# Without this adjustment, the 'service_to_daemon_types' lookup would fail, as
465+
# it would be searching for a non-existent entry called 'exporter
466+
if p['labels']['app'] == 'rook-ceph-exporter':
467+
sd.daemon_type = 'ceph-exporter'
468+
else:
469+
sd.daemon_type = p['labels']['app'].replace('rook-ceph-', '')
470+
461471
status = {
462472
'Pending': orchestrator.DaemonDescriptionStatus.starting,
463473
'Running': orchestrator.DaemonDescriptionStatus.running,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from rook.module import RookOrchestrator
2+
from orchestrator import raise_if_exception, OrchResult
3+
4+
try:
5+
from typing import Any
6+
except ImportError:
7+
pass
8+
9+
10+
def wait(m: RookOrchestrator, c: OrchResult) -> Any:
11+
return raise_if_exception(c)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import orchestrator
2+
from .fixtures import wait
3+
import pytest
4+
from unittest.mock import patch, PropertyMock
5+
6+
from rook.module import RookOrchestrator
7+
from rook.rook_cluster import RookCluster
8+
9+
10+
# we use this intermediate class as .rook_cluster property
11+
# is read only in the paretn class RookCluster
12+
class FakeRookCluster(RookCluster):
13+
def __init__(self):
14+
pass
15+
16+
17+
class TestRook(object):
18+
19+
@pytest.mark.parametrize("pods, expected_daemon_types", [
20+
(
21+
[
22+
{
23+
'name': 'ceph-rook-exporter',
24+
'hostname': 'host1',
25+
"labels": {'app': 'rook-ceph-exporter',
26+
'ceph_daemon_id': 'exporter'},
27+
'phase': 'Pending',
28+
'container_image_name': 'quay.io/ceph/ceph:v18',
29+
'container_image_id': 'docker-pullable://quay.io/ceph/ceph@sha256:f239715e1c7756e32a202a572e2763a4ce15248e09fc6e8990985f8a09ffa784',
30+
'refreshed': 'pod1_ts',
31+
'started': 'pod1_ts',
32+
'created': 'pod1_1ts',
33+
},
34+
{
35+
'name': 'rook-ceph-mgr-a-68c7b9b6d8-vjjhl',
36+
'hostname': 'host1',
37+
"labels": {'app': 'rook-ceph-mgr',
38+
'ceph_daemon_type': 'mgr',
39+
'ceph_daemon_id': 'a'},
40+
'phase': 'Failed',
41+
'container_image_name': 'quay.io/ceph/ceph:v18',
42+
'container_image_id': '',
43+
'refreshed': 'pod2_ts',
44+
'started': 'pod2_ts',
45+
'created': 'pod2_1ts',
46+
},
47+
{
48+
'name': 'rook-ceph-mon-a-65fb8694b4-mmtl5',
49+
'hostname': 'host1',
50+
"labels": {'app': 'rook-ceph-mon',
51+
'ceph_daemon_type': 'mon',
52+
'ceph_daemon_id': 'b'},
53+
'phase': 'Running',
54+
'container_image_name': 'quay.io/ceph/ceph:v18',
55+
'container_image_id': '',
56+
'refreshed': 'pod3_ts',
57+
'started': 'pod3_ts',
58+
'created': 'pod3_1ts',
59+
},
60+
{
61+
'name': 'rook-ceph-osd-0-58cbd7b65c-6cjnr',
62+
'hostname': 'host1',
63+
"labels": {'app': 'rook-ceph-osd',
64+
'ceph-osd-id': '0',
65+
'ceph_daemon_type': 'osd',
66+
'ceph_daemon_id': '0'},
67+
'phase': 'Succeeded',
68+
'container_image_name': 'quay.io/ceph/ceph:v18',
69+
'container_image_id': '',
70+
'refreshed': 'pod4_ts',
71+
'started': 'pod4_ts',
72+
'created': 'pod4_1ts',
73+
},
74+
# unknown pod: has no labels are provided, it shouldn't
75+
# be part of the output
76+
{
77+
'name': 'unknown-pod',
78+
'hostname': '',
79+
"labels": {'app': 'unkwon'},
80+
'phase': 'Pending',
81+
'container_image_name': 'quay.io/ceph/ceph:v18',
82+
'container_image_id': '',
83+
'refreshed': '',
84+
'started': '',
85+
'created': '',
86+
}
87+
],
88+
['ceph-exporter', 'mgr', 'mon', 'osd']
89+
)
90+
])
91+
def test_list_daemons(self, pods, expected_daemon_types):
92+
93+
status = {
94+
'Pending': orchestrator.DaemonDescriptionStatus.starting,
95+
'Running': orchestrator.DaemonDescriptionStatus.running,
96+
'Succeeded': orchestrator.DaemonDescriptionStatus.stopped,
97+
'Failed': orchestrator.DaemonDescriptionStatus.error,
98+
'Unknown': orchestrator.DaemonDescriptionStatus.unknown,
99+
}
100+
101+
fake_rook_cluster = FakeRookCluster()
102+
ro = RookOrchestrator('rook', None, self)
103+
with patch('rook.RookOrchestrator.rook_cluster',
104+
new_callable=PropertyMock,
105+
return_value=fake_rook_cluster):
106+
with patch.object(fake_rook_cluster, 'describe_pods') as mock_describe_pods:
107+
mock_describe_pods.return_value = pods
108+
dds = wait(ro, ro.list_daemons())
109+
assert len(dds) == len(expected_daemon_types)
110+
for i in range(0, len(dds)):
111+
assert dds[i].daemon_type == expected_daemon_types[i]
112+
assert dds[i].hostname == pods[i]['hostname']
113+
assert dds[i].status == status[pods[i]['phase']]
114+
assert dds[i].container_image_name == pods[i]['container_image_name']
115+
assert dds[i].container_image_id == pods[i]['container_image_id']
116+
assert dds[i].created == pods[i]['created']
117+
assert dds[i].last_configured == pods[i]['created']
118+
assert dds[i].last_deployed == pods[i]['created']
119+
assert dds[i].started == pods[i]['started']
120+
assert dds[i].last_refresh == pods[i]['refreshed']

0 commit comments

Comments
 (0)