Skip to content

Commit 74e3d41

Browse files
Merge pull request #278 from apel/release-3.3.1
Release 3.3.1 to master
2 parents 6fc105c + bed0e27 commit 74e3d41

18 files changed

+88
-35
lines changed

.github/workflows/build-pkgs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
run: |
2222
sudo apt-get update
2323
sudo apt-get install rpmlint
24-
- uses: actions/checkout@v3
24+
- uses: actions/checkout@v4
2525
with:
2626
# Get all branches and tags so the latest tag can be found for VERSION
2727
fetch-depth: 0
@@ -51,7 +51,7 @@ jobs:
5151
run: rpmlint ${{ steps.rpm.outputs.rpm_dir_path }}
5252

5353
- name: Upload artifact
54-
uses: actions/upload-artifact@v3.1.2
54+
uses: actions/upload-artifact@v3.1.3
5555
with:
5656
name: Binary and Source RPMs
5757
path: |

.github/workflows/codeql-analysis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434

3535
steps:
3636
- name: Checkout repository
37-
uses: actions/checkout@v3
37+
uses: actions/checkout@v4
3838

3939
# Initializes the CodeQL tools for scanning.
4040
- name: Initialize CodeQL

.github/workflows/docker.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
# Login against a Docker registry
3131
# https://github.com/docker/login-action
3232
name: Login to ${{ env.REGISTRY }}
33-
uses: docker/login-action@v2
33+
uses: docker/login-action@v3
3434
with:
3535
registry: ${{ env.REGISTRY }}
3636
username: ${{ github.actor }}
@@ -40,15 +40,15 @@ jobs:
4040
# https://github.com/docker/metadata-action
4141
name: Extract Docker metadata
4242
id: meta
43-
uses: docker/metadata-action@v4
43+
uses: docker/metadata-action@v5
4444
with:
4545
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
4646

4747
-
4848
# Build and push Docker image
4949
# https://github.com/docker/build-push-action
5050
name: Build and push Docker image
51-
uses: docker/build-push-action@v4.1.1
51+
uses: docker/build-push-action@v5.0.0
5252
with:
5353
# Only push containers to the registry on GitHub pushes,
5454
# not pull requests. GitHub won't let a rogue PR create a container

.github/workflows/unit-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ jobs:
88
strategy:
99
fail-fast: false
1010
matrix:
11-
python-version: ['2.x', '3.x']
11+
python-version: ['3.x']
1212
name: Python ${{ matrix.python-version }} test
1313
steps:
14-
- uses: actions/checkout@v3
14+
- uses: actions/checkout@v4
1515
- name: Set up Python
1616
uses: actions/setup-python@v4
1717
with:

.pre-commit-config.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,22 @@ repos:
1515
- id: check-added-large-files
1616
- id: check-merge-conflict
1717
- id: check-yaml
18+
- id: debug-statements
1819
- id: end-of-file-fixer
1920
- id: mixed-line-ending
2021
name: Force line endings to LF
2122
args: ['--fix=lf']
2223
- id: trailing-whitespace
2324

2425
- repo: https://github.com/pre-commit/pygrep-hooks
25-
rev: v1.9.0
26+
rev: v1.10.0
2627
hooks:
2728
- id: python-check-mock-methods
2829
- id: python-no-eval
2930
- id: python-no-log-warn
31+
- id: python-use-type-annotations
32+
33+
# Pre-commit CI config, see https://pre-commit.ci/
34+
ci:
35+
autofix_prs: false
36+
autoupdate_schedule: quarterly

CHANGELOG

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
Changelog for ssm
22
=================
3+
* Mon Oct 09 2023 Adrian Coveney <adrian.coveney@stfc.ac.uk> - 3.3.0-1
4+
- Added warning that BDII broker fetching will be deprecated in a future version.
5+
- Added non-zero exit status if sender or receiver crash.
6+
- Fixed SSM hanging if TCP connection drops by adding timeout.
7+
- Fixed directory queue system picking up sub-directories.
8+
- Fixed AMS messaging library dependency issue.
9+
- Fixed documentation for running a containerised receiver.
10+
- Fixed a few minor code issues.
11+
312
* Thu Jun 29 2023 Adrian Coveney <adrian.coveney@stfc.ac.uk> - 3.3.0-1
413
- Added destination queue to the log during startup to aid troubleshooting.
514
- Added check that the config file exists to allow for better error messages.

README.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,17 @@ using the [STOMP protocol](http://stomp.github.io/) or via the ARGO Messaging Se
1010
Messages are signed and may be encrypted during transit.
1111
Persistent queues should be used to guarantee delivery.
1212

13-
SSM is written in Python. Packages are available for RHEL 6 and 7, and
14-
Ubuntu Trusty.
13+
SSM is written in Python. Packages are available for RHEL 7, and Ubuntu Trusty.
1514

1615
For more information about SSM, see the [EGI wiki](https://wiki.egi.eu/wiki/APEL/SSM).
1716

1817
## Acknowledgements
1918

2019
<span>
21-
<img alt="STFC logo" src="https://github.com/GOCDB/gocdb/raw/dev/htdocs/images/UKRI_STF_Council-Logo_Horiz-RGB_crop.png" height="57" />
22-
<img alt="EU flag" src="https://github.com/GOCDB/gocdb/raw/dev/htdocs/images/eu_flag_yellow_low_150.png" height="51" />
23-
<img alt="EOSC-hub logo" src="https://github.com/GOCDB/gocdb/raw/dev/htdocs/images/eosc-hub-v-web_150.png" height="57" />
20+
<img alt="STFC logo" src="https://github.com/GOCDB/gocdb/raw/a3df819/htdocs/images/logos/ukri_stfc.png" height="57" />
2421
</span>
2522

26-
SSM is provided by [STFC](https://stfc.ukri.org/), a part of [UK Research and Innovation](https://www.ukri.org/), and is co-funded by the [EOSC-hub](https://www.eosc-hub.eu/) project (Horizon 2020) under Grant number 777536. Licensed under the [Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0).
23+
SSM is provided by [STFC](https://stfc.ukri.org/), a part of [UK Research and Innovation](https://www.ukri.org/). Licensed under the [Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0).
2724

2825
## Installing the RPM
2926

@@ -40,7 +37,7 @@ The Python STOMP library (N.B. versions between 3.1.1 (inclusive) and 5.0.0
4037

4138
The Python AMS library. This is only required if you want to use AMS. See here for details on obtaining an RPM: https://github.com/ARGOeu/argo-ams-library/
4239

43-
The Python ldap library
40+
The Python ldap library (N.B. versions before 3.4.0 (exclusive) are currently supported)
4441
* `yum install python-ldap`
4542

4643
Optionally, the Python dirq library (N.B. this is only required if your messages
@@ -211,8 +208,8 @@ add your messages using the `add` method.
211208
```
212209
docker run \
213210
-d --entrypoint ssmreceive \
214-
-v /path/to/downloaded/config/sender.cfg:/etc/apel/sender.cfg \
215-
-v /path/to/read/messages:/var/spool/apel/outgoing \
211+
-v /path/to/downloaded/config/receiver.cfg:/etc/apel/receiver.cfg \
212+
-v /path/to/read/messages:/var/spool/apel/ \
216213
-v /path/to/dns/file:/etc/apel/dns \
217214
-v /etc/grid-security:/etc/grid-security \
218215
-v /path/to/persistently/log:/var/log/apel \

apel-ssm.spec

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
%endif
55

66
Name: apel-ssm
7-
Version: 3.3.0
7+
Version: 3.3.1
88
%define releasenumber 1
99
Release: %{releasenumber}%{?dist}
1010
Summary: Secure stomp messenger
@@ -100,6 +100,15 @@ rm -rf $RPM_BUILD_ROOT
100100
%doc %_defaultdocdir/%{name}
101101

102102
%changelog
103+
* Mon Oct 09 2023 Adrian Coveney <adrian.coveney@stfc.ac.uk> - 3.3.0-1
104+
- Added warning that BDII broker fetching will be deprecated in a future version.
105+
- Added non-zero exit status if sender or receiver crash.
106+
- Fixed SSM hanging if TCP connection drops by adding timeout.
107+
- Fixed directory queue system picking up sub-directories.
108+
- Fixed AMS messaging library dependency issue.
109+
- Fixed documentation for running a containerised receiver.
110+
- Fixed a few minor code issues.
111+
103112
* Thu Jun 29 2023 Adrian Coveney <adrian.coveney@stfc.ac.uk> - 3.3.0-1
104113
- Added destination queue to the log during startup to aid troubleshooting.
105114
- Added check that the config file exists to allow for better error messages.

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Base requirements for ssm
22

33
argo-ams-library
4+
certifi<2020.4.5.2 # Used by AMS (via requests), 2020.4.5.2 dropped support for Python 2
45
stomp.py<5.0.0
56
python-daemon<=2.3.0 # 2.3.1 dropped support for Python 2
67
python-ldap<3.4.0 # python-ldap-3.4.0 dropped support for Python 2

scripts/ssm-build-deb.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
set -eu
1818

19-
TAG=3.3.0-1
19+
TAG=3.3.1-1
2020

2121
SOURCE_DIR=~/debbuild/source
2222
BUILD_DIR=~/debbuild/build

scripts/ssm-build-rpm.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
rpmdev-setuptree
1111

1212
RPMDIR=/home/rpmb/rpmbuild
13-
VERSION=3.3.0-1
13+
VERSION=3.3.1-1
1414
SSMDIR=apel-ssm-$VERSION
1515

1616
# Remove old sources and RPMS

ssm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import logging
2020
import sys
2121

22-
__version__ = (3, 3, 0)
22+
__version__ = (3, 3, 1)
2323

2424
LOG_BREAK = '========================================'
2525

ssm/agents.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,6 @@ def get_ssm_args(protocol, cp, log):
141141
elif protocol == Ssm2.AMS_MESSAGING:
142142
# Then we are setting up an SSM to connect to a AMS.
143143

144-
# TODO: See if setting use_ssl directly in Ssm2 constructor is ok.
145-
# 'use_ssl' isn't checked when using AMS (SSL is always used), but it
146-
# is needed for the call to the Ssm2 constructor below.
147-
use_ssl = None
148144
try:
149145
# We only need a hostname, not a port
150146
host = cp.get('broker', 'host')
@@ -254,6 +250,9 @@ def run_sender(protocol, brokers, project, token, cp, log):
254250
print('SSM failed to complete successfully. See log file for details.')
255251
log.error('Unexpected exception in SSM: %s', e)
256252
log.error('Exception type: %s', e.__class__)
253+
sender_failed = True
254+
else:
255+
sender_failed = False
257256

258257
try:
259258
sender.close_connection()
@@ -263,6 +262,8 @@ def run_sender(protocol, brokers, project, token, cp, log):
263262

264263
log.info('SSM has shut down.')
265264
log.info(LOG_BREAK)
265+
if sender_failed:
266+
sys.exit(1)
266267

267268

268269
def run_receiver(protocol, brokers, project, token, cp, log, dn_file):
@@ -348,15 +349,24 @@ def run_receiver(protocol, brokers, project, token, cp, log, dn_file):
348349
log.info('Received the shutdown signal: %s', e)
349350
ssm.shutdown()
350351
dc.close()
352+
receiver_failed = True
351353
except Exception as e:
352354
log.error('Unexpected exception: %s', e)
353355
log.error('Exception type: %s', e.__class__)
354356
log.error('The SSM will exit.')
355357
ssm.shutdown()
356358
dc.close()
359+
receiver_failed = True
360+
# Currently won't run the else statement due to the while loop in the reciever
361+
# Leaving here in case of future refactoring, but commented out so the unreachable
362+
# code isn't flagged by tests
363+
# else:
364+
# receiver_failed = False
357365

358366
log.info('Receiving SSM has shut down.')
359367
log.info(LOG_BREAK)
368+
if receiver_failed:
369+
sys.exit(1)
360370

361371

362372
def get_dns(dn_file, log):

ssm/brokers.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class StompBrokerGetter(object):
4343
def __init__(self, bdii_url):
4444
"""Set up the LDAP connection and strings which are re-used."""
4545
# Set up the LDAP connection
46+
logging.warning('LDAP is deprecated and will be removed in an upcoming version, '
47+
'please set host locally in SSM config.')
4648
log.debug('Connecting to %s...', bdii_url)
4749
self._ldap_conn = ldap.initialize(bdii_url)
4850

@@ -99,7 +101,7 @@ def _get_broker_details(self, service_type):
99101
return broker_details
100102

101103
def _broker_in_network(self, broker_id, network):
102-
"""Check that a GlueServiceUniqueID is part of a specified netowrk."""
104+
"""Check that a GlueServiceUniqueID is part of a specified network."""
103105
ldap_filter = '(&(GlueServiceDataKey=cluster)(GlueChunkKey=GlueServiceUniqueID=%s))' \
104106
% broker_id
105107
attrs = [self._service_data_value_key]

ssm/message_directory.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@ def _get_messages(self, sort_by_mtime=False):
8787
"""
8888
try:
8989
# Get a list of files under self.directory_path
90-
# in an arbitrary order.
91-
file_name_list = os.listdir(self.directory_path)
90+
# in an arbitrary order (ignoring directories).
91+
file_name_list = [file for file in os.listdir(self.directory_path)
92+
if os.path.isfile(os.path.join(self.directory_path, file))]
9293

9394
if sort_by_mtime:
9495
# Working space to hold the unsorted messages

ssm/ssm2.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,12 @@ def _send_msg_ams(self, text, msgid):
390390
message = AmsMessage(data=to_send,
391391
attributes={'empaid': msgid}).dict()
392392

393-
argo_response = self._ams.publish(self._dest, message, retry=3)
393+
argo_response = self._ams.publish(self._dest, message, retry=3, timeout=10)
394394
return argo_response['messageIds'][0]
395+
else:
396+
# We ignore empty messages as there is no point sending them.
397+
# (STOMP did require empty messages to keep the connection alive.)
398+
return None
395399

396400
def pull_msg_ams(self):
397401
"""Pull 1 message from the AMS and acknowledge it."""
@@ -411,7 +415,8 @@ def pull_msg_ams(self):
411415

412416
for msg_ack_id, msg in self._ams.pull_sub(self._listen,
413417
messages_to_pull,
414-
retry=3):
418+
retry=3,
419+
timeout=10):
415420
# Get the AMS message id
416421
msgid = msg.get_msgid()
417422
# Get the SSM dirq id
@@ -440,7 +445,7 @@ def pull_msg_ams(self):
440445
# it can move the offset for the next subscription pull
441446
# (basically acknowledging pulled messages)
442447
if ackids:
443-
self._ams.ack_sub(self._listen, ackids, retry=3)
448+
self._ams.ack_sub(self._listen, ackids, retry=3, timeout=10)
444449

445450
def send_ping(self):
446451
"""Perform connection stay-alive steps.

test/test_crypto.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
verify_cert, \
1818
CryptoException
1919

20-
# Set up logging - is this necessary?
2120
logging.basicConfig()
22-
log = logging.getLogger('SSM')
2321

2422

2523
class TestEncryptUtils(unittest.TestCase):

test/test_message_directory.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"""This module contains test cases for the MessageDirectory class."""
1515
from __future__ import print_function
1616

17+
import os
1718
import shutil
1819
import tempfile
1920
import time
@@ -27,7 +28,7 @@ class TestMessageDirectory(unittest.TestCase):
2728

2829
def setUp(self):
2930
"""Create a MessageDirectory class on top of a temporary directory."""
30-
self.tmp_dir = tempfile.mkdtemp(prefix='message_directory')
31+
self.tmp_dir = tempfile.mkdtemp(prefix='message_directory_')
3132
self.message_directory = MessageDirectory(self.tmp_dir)
3233

3334
def test_add_and_get(self):
@@ -137,6 +138,19 @@ def test_remove(self):
137138
# Check the count method returns the expected value.
138139
self.assertEqual(self.message_directory.count(), 0)
139140

141+
def test_dir_in_dir(self):
142+
"""Check that directories inside the queue are being ignored."""
143+
self.longMessage = True # Include normal unittest output before custom message.
144+
145+
# Add a single test file (closing it to ensure this works on Unix)
146+
handle, _path = tempfile.mkstemp(dir=self.tmp_dir)
147+
os.close(handle)
148+
# Add a directory (to ignore)
149+
tempfile.mkdtemp(prefix='extra_directory_', dir=self.tmp_dir)
150+
151+
self.assertEqual(self.message_directory.count(), 1, "Expected just one file, "
152+
"but greater result implies that directory is being counted.")
153+
140154
def tearDown(self):
141155
"""Remove test directory and all contents."""
142156
try:

0 commit comments

Comments
 (0)