Skip to content

Commit ea9be4a

Browse files
authored
Merge pull request xcat2#239 from Obihoernchen/ci
Add CI pipeline
2 parents 2644ad8 + fa60516 commit ea9be4a

7 files changed

Lines changed: 101 additions & 32 deletions

File tree

.github/workflows/ci.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
ShellCheck:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v7
15+
- name: Run ShellCheck (errors only)
16+
# Check every tracked file that has a .sh extension or an sh/bash
17+
# shebang. SC2148 (missing shebang) is excluded because many .sh
18+
# files are sourced fragments or dracut hooks; ShellCheck then
19+
# falls back to checking them as bash.
20+
run: |
21+
{
22+
git ls-files '*.sh'
23+
git ls-files | while IFS= read -r f; do
24+
[ -f "$f" ] || continue
25+
head -c 200 "$f" | head -n 1 | \
26+
grep -qE '^#!.*[/ ](sh|bash|dash|ash|ksh)([ \t]|$)' && echo "$f"
27+
done
28+
} | sort -u | xargs -d '\n' shellcheck --severity=error --exclude=SC2148
29+
30+
python-compileall:
31+
name: Python compileall
32+
runs-on: ubuntu-latest
33+
env:
34+
# One entry per Python version shipped by the distros confluent
35+
# targets, limited to versions actions/setup-python still provides
36+
# on current runners (sles15/alma8 ship 3.6, which is unavailable).
37+
# Newline-separated so it feeds both setup-python (multiline input)
38+
# and the shell loop below (word-split on whitespace).
39+
PYTHON_VERSIONS: |
40+
3.8
41+
3.9
42+
3.10
43+
3.12
44+
3.13
45+
3.14
46+
steps:
47+
- uses: actions/checkout@v7
48+
- uses: actions/setup-python@v6
49+
with:
50+
python-version: ${{ env.PYTHON_VERSIONS }}
51+
- name: Compile all Python files
52+
run: |
53+
rc=0
54+
for v in $PYTHON_VERSIONS; do
55+
echo "::group::Python $v"
56+
if "python$v" -W error -m compileall -q -x '/\.git/' .; then
57+
echo "::endgroup::"
58+
else
59+
echo "::endgroup::"
60+
echo "::error::Python $v compileall failed"
61+
rc=1
62+
fi
63+
done
64+
exit "$rc"

confluent_osdeploy/el7-diskless/profiles/default/scripts/image2disk.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ def fixup(rootdir, vols):
173173
for vol in vols:
174174
if vol['mount'] == '/boot/efi':
175175
targdev = vol['targetdisk']
176-
partnum = re.search('(\d+)$', targdev).group(1)
177-
targblock = re.search('(.*)\d+$', targdev).group(1)
176+
partnum = re.search(r'(\d+)$', targdev).group(1)
177+
targblock = re.search(r'(.*)\d+$', targdev).group(1)
178178
if targblock:
179179
if targblock.endswith('p') and 'nvme' in targblock:
180180
targblock = targblock[:-1]
@@ -231,7 +231,7 @@ def install_to_disk(imgpath):
231231
deflvmsize += fs['initsize']
232232
minlvmsize += fs['minsize']
233233
else:
234-
plainvols[int(re.search('(\d+)$', fs['device'])[0])] = fs
234+
plainvols[int(re.search(r'(\d+)$', fs['device'])[0])] = fs
235235
with open('/tmp/installdisk') as diskin:
236236
instdisk = diskin.read()
237237
instdisk = '/dev/' + instdisk

confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/image2disk.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ def fixup(rootdir, vols):
204204
for vol in vols:
205205
if vol['mount'] == '/boot/efi':
206206
targdev = vol['targetdisk']
207-
partnum = re.search('(\d+)$', targdev).group(1)
208-
targblock = re.search('(.*)\d+$', targdev).group(1)
207+
partnum = re.search(r'(\d+)$', targdev).group(1)
208+
targblock = re.search(r'(.*)\d+$', targdev).group(1)
209209
if targblock:
210210
if targblock.endswith('p') and 'nvme' in targblock:
211211
targblock = targblock[:-1]
@@ -263,7 +263,7 @@ def install_to_disk(imgpath):
263263
deflvmsize += fs['initsize']
264264
minlvmsize += fs['minsize']
265265
else:
266-
plainvols[int(re.search('(\d+)$', fs['device'])[0])] = fs
266+
plainvols[int(re.search(r'(\d+)$', fs['device'])[0])] = fs
267267
with open('/tmp/installdisk') as diskin:
268268
instdisk = diskin.read()
269269
instdisk = '/dev/' + instdisk

confluent_server/confluent/collective/manager.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,28 +206,30 @@ async def follow_leader(remote, leader):
206206
exitcause = await cfm.follow_channel(remote)
207207
newleader = exitcause.get('newleader', None)
208208
finally:
209+
handled = False
209210
if cleanexit:
210211
log.log({'info': 'Previous following cleanly closed',
211212
'subsystem': 'collective'})
212-
return
213-
if newleader:
213+
handled = True
214+
if not handled and newleader:
214215
log.log(
215216
{'info': 'Previous leader directed us to join new leader {}'.format(newleader)})
216217
try:
217218
if await connect_to_leader(None, get_myname(), newleader):
218-
return
219+
handled = True
219220
except Exception:
220221
log.log({'error': 'Unknown error attempting to connect to {}, check trace log'.format(newleader), 'subsystem': 'collective'})
221222
cfm.logException()
222-
log.log({'info': 'Current leader ({0}) has disappeared, restarting '
223-
'collective membership'.format(leader), 'subsystem': 'collective'})
224-
# The leader has folded, time to startup again...
225-
follower = None
226-
await cfm.stop_following()
227-
currentleader = None
228-
if retrythread is None: # start a recovery
229-
retrythread = tasks.spawn_task_after(
230-
random.random(), start_collective)
223+
if not handled:
224+
log.log({'info': 'Current leader ({0}) has disappeared, restarting '
225+
'collective membership'.format(leader), 'subsystem': 'collective'})
226+
# The leader has folded, time to startup again...
227+
follower = None
228+
await cfm.stop_following()
229+
currentleader = None
230+
if retrythread is None: # start a recovery
231+
retrythread = tasks.spawn_task_after(
232+
random.random(), start_collective)
231233

232234
async def _create_tls_connection(host, port):
233235
cloop = asyncio.get_running_loop()

confluent_server/confluent/config/configmanager.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,9 @@ async def relay_slaved_requests(name, listener):
782782
msg = await lh.get_next_msg()
783783
except Exception:
784784
msg = None
785+
except Exception:
786+
# unexpected loss or misbehavior of the follower ends the relay
787+
logException()
785788
finally:
786789
try:
787790
listener.close()
@@ -798,10 +801,10 @@ async def relay_slaved_requests(name, listener):
798801
*[_push_rpc(cfgstreams[s]['stream'], payload) for s in cfgstreams])
799802
if membership_callback:
800803
membership_callback()
801-
if not cfgstreams and not cfgleader: # last one out, set cfgleader to boolean to mark dead collective
802-
await stop_following(True)
803-
return False
804-
return True
804+
if not cfgstreams and not cfgleader: # last one out, set cfgleader to boolean to mark dead collective
805+
await stop_following(True)
806+
return False
807+
return True
805808

806809
lastheartbeat = None
807810
async def check_leader():

confluent_server/confluent/log.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ def initSizeRollingCount(self):
396396
prefix = baseName + "."
397397
if dirName not in self.dirContents or self.dirContents[dirName][1] < time.time():
398398
self.dirContents[dirName] = (os.listdir(dirName), time.time() + 5)
399-
matchexp = re.compile(f'^{prefix}\.\d+$')
399+
matchexp = re.compile(rf'^{prefix}\.\d+$')
400400
fileNames = [f for f in self.dirContents[dirName][0]
401401
if matchexp.match(f)]
402402
plen = len(prefix)

confluent_server/confluent/plugins/hardwaremanagement/enos.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,12 @@ def gather_data(configmanager, creds, node):
152152
nssh = enos_login(node=node, configmanager=configmanager, creds=creds)
153153
switch_lines = enos_version(ssh=nssh)
154154
switch_data = {}
155-
sysinfo = {"Product name": {"regex": ".*RackSwitch (\w+)"},
156-
"Serial Number": {"regex": "ESN\s*\w*\s*: ([\w-]+)"},
157-
"Board Serial Number": {"regex": "Switch Serial No: (\w+)"},
158-
"Model": {"regex": "MTM\s*\w*\s*: ([\w-]+)"},
159-
"FRU Number": {"regex": "Hardware Part\s*\w*\s*: (\w+)"},
160-
"Airflow": {"regex": "System Fan Airflow\s*\w*\s*: ([\w-]+)"},
155+
sysinfo = {"Product name": {"regex": r".*RackSwitch (\w+)"},
156+
"Serial Number": {"regex": r"ESN\s*\w*\s*: ([\w-]+)"},
157+
"Board Serial Number": {"regex": r"Switch Serial No: (\w+)"},
158+
"Model": {"regex": r"MTM\s*\w*\s*: ([\w-]+)"},
159+
"FRU Number": {"regex": r"Hardware Part\s*\w*\s*: (\w+)"},
160+
"Airflow": {"regex": r"System Fan Airflow\s*\w*\s*: ([\w-]+)"},
161161
}
162162

163163
invinfo = {
@@ -233,7 +233,7 @@ def gather_data(configmanager, creds, node):
233233
sysfw = {"Software Version": "Unknown", "Boot kernel": "Unknown"}
234234
for line in switch_lines:
235235
for key in sysfw.keys():
236-
regex = f"{key}\s*\w*\s* ([0-9.]+)"
236+
regex = rf"{key}\s*\w*\s* ([0-9.]+)"
237237
match = re.match(re.compile(regex), line)
238238
if match:
239239
sysfw[key] = match.group(1)
@@ -250,7 +250,7 @@ def gather_psus(data):
250250
# others are:
251251
# Internal Power Supply: On
252252
if "Power Supply" in line:
253-
match = re.match(re.compile("Power Supply (\d)+.*"), line)
253+
match = re.match(re.compile(r"Power Supply (\d)+.*"), line)
254254
if match:
255255
psu = match.group(1)
256256
if psu not in psus:
@@ -280,7 +280,7 @@ def gather_fans(data):
280280
for line in data:
281281
# look for presence of fans
282282
if "Fan" in line:
283-
match = re.match(re.compile("Fan (\d)+.*"), line)
283+
match = re.match(re.compile(r"Fan (\d)+.*"), line)
284284
if match:
285285
fan = match.group(1)
286286
if match:

0 commit comments

Comments
 (0)