Skip to content

Commit 4aea232

Browse files
committed
Fix healthcheck for newer manila versions
Manila introduced in the main branch a manila-manage patch that makes the healthcheck script no longer 100% compatible with newer version (E+) [1]. While in the long term the idea is to change this script to use a json representation of the output, we need to keep it compatible with previous releases, because the operator is supposed to manage (at the time of writing) Manila versions that go from Antelope to Flamingo. This patch updates the service parsing table based on the layout established in manila-manage command [2]. [1] https://review.opendev.org/c/openstack/manila/+/899295 [2] https://github.com/openstack/manila/blob/master/manila/cmd/manage.py Signed-off-by: Francesco Pantano <fpantano@redhat.com>
1 parent b5b3061 commit 4aea232

File tree

1 file changed

+85
-37
lines changed

1 file changed

+85
-37
lines changed

templates/manila/bin/healthcheck.py

Lines changed: 85 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@
5252
STATE_UP = ":-)"
5353
STATUS_ENABLED = "enabled"
5454

55+
'''
56+
manila-manage returns services using the following layout:
57+
58+
# SERVICE LAYOUT
59+
60+
| binary | -> 0
61+
| host | -> 1
62+
| zone | -> 2
63+
| status | -> 3
64+
| state | -> 4
65+
| udated_at | -> 5
66+
67+
The layout is defined in the upstream manila-manage code [1].
68+
Every time a manila-manage command is performed, we can resolve the position
69+
of each field, and we can easily decode into a dict.
70+
71+
[1] https://github.com/openstack/manila/blob/master/manila/cmd/manage.py#L376
72+
'''
73+
74+
5575
class HTTPServerV6(server.HTTPServer):
5676
address_family = socket.AF_INET6
5777

@@ -96,6 +116,47 @@ def initialize_class(cls, binary, config_dir):
96116
# Store the filters used to find out services.
97117
cls.services_filters = services_filters
98118

119+
@staticmethod
120+
def get_status(service):
121+
"""
122+
Because status is either enabled or disabled, this function looks for
123+
it by iterating the array; by doing this it does not ave to rely on a
124+
particular position
125+
"""
126+
return STATUS_ENABLED if STATUS_ENABLED in service else "disabled"
127+
128+
@staticmethod
129+
def validate_line(service):
130+
"""
131+
Process the line if there's at least one element
132+
"""
133+
return False if ((len(service) - 1) <= 0) else True
134+
135+
@staticmethod
136+
def get_state(service):
137+
"""
138+
Because STATE_UP has a special symbol, the function does not need to
139+
search for it at a given position, but it can match it by iterating
140+
the array and return a negative result if the symbol is not found
141+
"""
142+
return STATE_UP if STATE_UP in service else "XXX"
143+
144+
@staticmethod
145+
def get_hostgroup(service):
146+
"""
147+
As per the layout defined in the manila-manage command, hostgroup is
148+
always the second entry of the table
149+
"""
150+
return service[1] if len(service) > 1 else None
151+
152+
@staticmethod
153+
def get_service_name(service):
154+
"""
155+
Service name is always the first entry of the table defined by the
156+
manila-manage command
157+
"""
158+
return service[0] if service else None
159+
99160
@staticmethod
100161
def check_service(services, **filters):
101162
# Check if services were already created and are registered in the db
@@ -114,49 +175,36 @@ def check_service(services, **filters):
114175
raise ServiceNotUp()
115176

116177
def _parse_service_list_output(self, services_list):
178+
# reuse the existing BINARIES tuple to resolve the allowed services
179+
# and prefix each item
180+
allowed_services = tuple('manila-{}'.format(item) for item in BINARIES)
117181
# Decode the characters, remove the line splits and the
118182
# blank spaces
119183
services_list = services_list.decode('utf-8').split('\n')
120-
parsed_service_list = []
184+
services = []
121185
for service in services_list:
122-
if "DEBUG" in service:
186+
# clean up tokens of the current line
187+
tokens = [token for token in service.split() if token]
188+
# invalid line: stop early and move to the next item, no need to
189+
# try to process each element
190+
if not self.validate_line(tokens):
123191
continue
124-
parsed_service_list.append(service)
125-
126-
if not parsed_service_list:
127-
raise ServiceNotFoundException(filters={})
128-
129-
parsed_service_list = [
130-
service.split() for service in parsed_service_list]
131-
132-
# First line is related to the headers. We don't care about the
133-
# updated at, so we drop it and sanitize the strings.
134-
services_list_headers = parsed_service_list[0]
135-
columns_to_ignore_starts_at = (
136-
services_list_headers.index("Updated")
137-
if "Updated" in services_list_headers else None)
138-
139-
if not columns_to_ignore_starts_at:
192+
# First line is related to the headers. We don't care about the
193+
# updated at, so we ignore it
194+
if "Binary" in tokens:
195+
continue
196+
# Process a valid line for a given service and fill the dict
197+
service_name = self.get_service_name(tokens)
198+
if service_name and service_name in allowed_services:
199+
services.append({
200+
'binary': service_name,
201+
'host': self.get_hostgroup(tokens),
202+
'status': self.get_status(tokens),
203+
'state': self.get_state(tokens),
204+
})
205+
if not services:
140206
raise ServiceNotFoundException(filters={})
141-
142-
services_list_headers = (
143-
services_list_headers[0:columns_to_ignore_starts_at])
144-
services_list_headers = (
145-
[header.lower() for header in services_list_headers])
146-
147-
# Remove the headers from the list, so we can iterate on the items
148-
parsed_service_list.pop(0)
149-
150-
# Finally, we can get a dictionary out of the manila-manage command.
151-
parsed_services_dict_list = []
152-
153-
for service in parsed_service_list:
154-
if service:
155-
service_dict = {}
156-
for i, header in enumerate(services_list_headers):
157-
service_dict[header] = service[i]
158-
parsed_services_dict_list.append(service_dict)
159-
return parsed_services_dict_list
207+
return services
160208

161209
def do_GET(self):
162210
try:

0 commit comments

Comments
 (0)