Skip to content

Commit e935b6f

Browse files
urfeexurrsk
andauthored
Persist socat state (#2)
* Make socat state persist over reboots * Update tool-comm-forwarder-frontend/src/assets/i18n/en.json Co-authored-by: Rune Søe-Knudsen <[email protected]> * Added a text when the server is stopped --------- Co-authored-by: Rune Søe-Knudsen <[email protected]>
1 parent e565a8b commit e935b6f

File tree

4 files changed

+52
-8
lines changed

4 files changed

+52
-8
lines changed

manifest.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ artifacts:
2626
mounts:
2727
- mount: tmpfs:/tmp
2828
access: rw
29+
- mount: persistent:/data
30+
access: rw
2931
devices:
3032
- type: ttyTool
3133
ingress:

tool-comm-forwarder-backend/src/socat_server.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import subprocess
22
import json
33
import logging
4+
import os
45
import sys
56

67
import flask
@@ -20,6 +21,7 @@
2021
SOCAT_COMMAND = ["socat", f"tcp-l:{PORT},reuseaddr,fork", "file:/dev/ur-ttylink/ttyTool,nonblock,raw,waitlock=/tmp/lock_tty"]
2122
STOP_SOCAT_COOMAND = "killall -9 socat 2> /dev/null"
2223
IS_SOCAT_SERVER_RUNNING_COMMAND = f"socat /dev/null TCP:127.0.0.1:{PORT}"
24+
STATUS_FILENAME = "/data/socat_server_status.json"
2325

2426
app = Flask(__name__)
2527

@@ -46,30 +48,37 @@ def socat_server():
4648
flask.Response: A Flask response with a success key, telling whether the command was successful or not.
4749
"""
4850
action = request.get_json()["action"]
51+
response = None
4952
if action == "start":
5053
result = subprocess.Popen(SOCAT_COMMAND, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
5154
try:
5255
# wait 0.2 seconds for errors
5356
_, stderr = result.communicate(timeout=0.2)
5457
if result.returncode != 0:
5558
logger.error(f"Failed to start socat server. Error message {stderr}")
56-
return create_response({"success": False})
59+
60+
response = create_response({"success": False})
5761
except subprocess.TimeoutExpired: # If timeout expired the server is running
5862
logger.info("Started socat server")
59-
return create_response({"success": True})
63+
response = create_response({"success": True})
6064

6165
elif action == "stop":
6266
result = subprocess.run(STOP_SOCAT_COOMAND, capture_output=True, shell=True)
6367
if result.returncode == 0:
6468
logger.info("Stopped socat server")
65-
return create_response({"success": True})
69+
response = create_response({"success": True})
6670
else:
6771
logger.error(f"Failed to stop socat server. Error message {result.stderr}")
68-
return create_response({"success": False})
72+
response = create_response({"success": False})
6973

7074
else:
7175
logger.error(f"Unknown action received! Action received {action}")
72-
return create_response({"success": False})
76+
response = create_response({"success": False})
77+
78+
with open(STATUS_FILENAME, "wb") as status_file:
79+
running_response = is_server_running()
80+
status_file.write(running_response.data)
81+
return response
7382

7483

7584
@app.route("/is_server_running", methods=["GET"])
@@ -85,5 +94,36 @@ def is_server_running(): # handle a message
8594
else:
8695
return create_response({"running": False})
8796

97+
def recover_from_state(running: bool):
98+
"""Recovers the socat server to the given state
99+
100+
Args:
101+
running (bool): Whether the server should be running or not
102+
"""
103+
if running:
104+
result = subprocess.Popen(SOCAT_COMMAND, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
105+
try:
106+
# wait 0.2 seconds for errors
107+
_, stderr = result.communicate(timeout=0.2)
108+
if result.returncode != 0:
109+
logger.error(f"Failed to recover socat server. Error message {stderr}")
110+
except subprocess.TimeoutExpired: # If timeout expired the server is running
111+
logger.info("Recovered socat server to running state")
112+
else:
113+
result = subprocess.run(STOP_SOCAT_COOMAND, capture_output=True, shell=True)
114+
if result.returncode == 0:
115+
logger.info("Recovered socat server to stopped state")
116+
else:
117+
logger.error(f"Failed to stop socat server during recovery. Error message {result.stderr}")
118+
88119
if __name__ == '__main__':
89-
serve(app, host='0.0.0.0', port=52762)
120+
if os.path.exists(STATUS_FILENAME):
121+
logger.info("Loading socat state from file")
122+
with open(STATUS_FILENAME, "rb") as status_file:
123+
bytes_data = status_file.read()
124+
try:
125+
data = json.loads(bytes_data.decode("utf-8"))
126+
recover_from_state(data["running"])
127+
except Exception as e:
128+
logger.error(f"Failed to load socat server state from file. Error: {e}")
129+
serve(app, host='0.0.0.0', port=52762)

tool-comm-forwarder-frontend/src/app/components/tool-comm-forwarder-application/tool-comm-forwarder-application.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ <h2 class="header" [textContent]="baseTranslationKey + '.socat-server.header' |
2222
</ur-button>
2323
</div>
2424
<p *ngIf="canStopServer() && !canStartServer()" class="info-text" [textContent]="baseTranslationKey + '.socat-server.server-running-text' | translate"></p>
25+
<p *ngIf="!canStopServer() && canStartServer()" class="info-text" [textContent]="baseTranslationKey + '.socat-server.server-stopped-text' | translate"></p>
2526
</div>
2627
</div>

tool-comm-forwarder-frontend/src/assets/i18n/en.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"nodes": {
44
"universal-robots-tool-comm-forwarder-tool-comm-forwarder-application": {
55
"title": "Tool Communication Forwarder",
6-
"supportiveText": "URCap to forward toool communication to the network",
6+
"supportiveText": "URCap to forward tool communication to the network",
77
"description": {
88
"line1": "URCapX to support relaying the RS-485 communication device in a UR robot to a remote PC.",
99
"line2": "It starts a socat server to relay the tool communication device to the network socket on port 54321."
@@ -14,7 +14,8 @@
1414
"start": "Start",
1515
"stop": "Stop"
1616
},
17-
"server-running-text": "Socat server is running on port 54321 forwarding tool communication to the network."
17+
"server-running-text": "Socat server is running on port 54321 forwarding tool communication to the network. This state is persisted and remains unchanged after a restart.",
18+
"server-stopped-text": "Socat server not running. This state is persisted and remains unchanged after a restart."
1819
}
1920
}
2021
}

0 commit comments

Comments
 (0)