Closed reubenmiller closed 4 months ago
I've created a branch on my fork which includes all of the files in the "Additional context" section:
The following changes are implemented:
--child -
c8ylp
command to connect to the container using the Cumulocity IoT PassThrough connection type of the Cloud Remote Access feature).Note: some other service managers like s6 also support socket activation, check out this PR for an example: https://github.com/eclipse/mosquitto/pull/2346/files
The PR #3006 resolved the following part.
Use a direct connection to the Cumulocity IoT URL instead of using the local c8y proxy service (as the service is maintained by the tedge-mapper-c8y service) - (technically this will be reverting the change where we switched to using the local c8y proxy)
The rest of requirements were resolved by #3007 (this is the main PR for this issue I would say)
Is your feature improvement request related to a problem? Please describe.
Using the Cumulocity IoT Remote Access feature to connect to a device via SSH is limiting as the
c8y-remote-access-plugin
process is spawned by thetedge-mapper-c8y
process, meaning that any command used the result in restarting the tedge-mapper-c8y service will disconnect the ssh session.Due to this limitation, the following actions are not possible:
Describe the solution you'd like
On devices which use SystemD, use a socket-activated service to launch the c8y-remote-access-plugin process which is independent from the tedge-mapper-c8y service.
In order to get full independence, the following changes would have to be done:
Important Notes about socket activated services
Describe alternatives you've considered
Alternatively, the SystemD KillMode of the tedge-mapper-c8y service could be changed to
process
(from the defaultcontrol-group
), however this is a best practice as it could result in orphaned processes, and it would mean that the tedge-mapper-service would have to managed any child process launched by itself so it could prevent said orphaned processes (this is currently managed by SystemD).Additional context
A detailed guide to how a socket activated service would work to launch an independent c8y-remote-access-plugin process:
The tedge-mapper-c8y will read the
c8y_RemoteAccessConnect
file, to determine which script to execute upon receiving a c8y SmartREST static message id530
, in this case it will call thepublish_to_socket.sh
script. Thepublish_to_socket.sh
script will publish the received message (read from arguments) and publish the same message to a socket. It then waits for a given response from the socket to confirm that the message was received and successful.The
c8y-remote-access-plugin.socket
is the systemd socket definition file which tells systemd to create a specific socket (either TCP or UNIX socket) and then when a client connects to the socket, systemd will accept the connection and spawn a new service based on the service template definition (c8y-remote-access-plugin@.service
), which in turn will start thec8y-remote-access-plugin
process. This results in one service per connection, however once the c8y-remote-access-plugin process exists, systemd will eventually cleanup the related service.Below shows some files which can be used to show the moving pieces:
file: /etc/tedge/operations/c8y/c8y_RemoteAccessConnect
The c8y operation definition file which will communicate with the socket to send a new request to open up a c8y-remote-access session.
file: /usr/bin/publish_to_socket.sh
A generic script used to communicate with a socket to publish a message and then read from the socket to confirm that the message results in a "successful action" (it just uses simple string matching to determine this, but we could do a more formal handshake as defined by c8y-remote-access-plugin).
file: /lib/systemd/system/c8y-remote-access-plugin.socket
SystemD socket definition which tells SystemD to create a socket and upon connection, create a new service based on the template and pass the current socket to it:
file: /lib/systemd/system/c8y-remote-access-plugin@.service
SystemD service which calls the c8y-remote-access-plugin process with the information received from the socket. c8y-remote-access-plugin can send information back to the socket by just writing to stdout (Standard Output).
Note: The
c8y-remote-access-plugin
example has been modified so that the--child
flag will read its values from stdin as denoted by the posix convention-
. TheStandardInput=socket
systemd setting specifies that the socket should be mapped to standard input, where it can be read like any normal standard input (meaning that the process does not need to know it is reading from a socket, just stdin).