]> git.corax.cc Git - toolbox/commitdiff
utils: Add interceptor and injector for IPC PubSub messages
authorMatthias Kruk <m@m10k.eu>
Sat, 1 Oct 2022 06:02:45 +0000 (15:02 +0900)
committerMatthias Kruk <m@m10k.eu>
Sat, 1 Oct 2022 06:02:45 +0000 (15:02 +0900)
Because the IPC module uses the file system to exchange messages,
remote systems cannot communicate without a shared file system such
as NFS. However, NFS may not be an option due to resource and
security constraints.

This commit adds the ipc-tap and ipc-inject utilities, which can be
used to bridge messages over an SSH connection. As the name suggests,
the ipc-tap utility taps into topics and outputs messages published
on those topics to standard output.
The ipc-inject reads messages from standard input and injects them
into local PubSub topics.

Makefile
utils/ipc-inject.sh [new file with mode: 0755]
utils/ipc-tap.sh [new file with mode: 0755]

index 1f060d56b80748a94269c5aa5b50aac339524fa4..e84b6548fd42ca628b5d9d933224281466062712 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,14 +17,19 @@ install:
        mkdir -p $(DESTDIR)/var/lib/toolbox/ipc
        cp toolbox.sh $(DESTDIR)/$(PREFIX)/share/toolbox/.
        cp -r include $(DESTDIR)/$(PREFIX)/share/toolbox/.
+       cp -r utils   $(DESTDIR)/$(PREFIX)/share/toolbox/.
        chown -R root.root $(DESTDIR)/$(PREFIX)/share/toolbox
        find $(DESTDIR)/$(PREFIX)/share/toolbox -type d -exec chmod 755 {} \;
        find $(DESTDIR)/$(PREFIX)/share/toolbox -type f -exec chmod 644 {} \;
        chmod -R 755 $(DESTDIR)/$(PREFIX)/share/toolbox
        ln -sf $(PREFIX)/share/toolbox/toolbox.sh $(DESTDIR)/$(PREFIX)/bin/toolbox.sh
+       ln -sf $(PREFIX)/share/toolbox/utils/ipc-tap.sh $(DESTDIR)/$(PREFIX)/bin/ipc-tap
+       ln -sf $(PREFIX)/share/toolbox/utils/ipc-inject.sh $(DESTDIR)/$(PREFIX)/bin/ipc-inject
 
 uninstall:
        rm $(DESTDIR)/$(PREFIX)/bin/toolbox.sh
+       rm $(DESTDIR)/$(PREFIX)/bin/ipc-tap
+       rm $(DESTDIR)/$(PREFIX)/bin/ipc-inject
        rm -rf $(DESTDIR)/$(PREFIX)/share/toolbox
 
 .PHONY: $(PHONY)
diff --git a/utils/ipc-inject.sh b/utils/ipc-inject.sh
new file mode 100755 (executable)
index 0000000..b0f418d
--- /dev/null
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+# ipc-inject.sh - Injector for toolbox IPC PubSub messages
+# Copyright (C) 2022 Matthias Kruk
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+signal_handler() {
+       signal_received=1
+}
+
+main() {
+       local endpoint
+       local message
+       declare -gi signal_received
+
+       signal_received=0
+
+       if ! opt_parse "$@"; then
+               return 1
+       fi
+
+       if ! endpoint=$(ipc_endpoint_open); then
+               return 1
+       fi
+
+       log_info "Using endpoint $endpoint"
+       trap signal_handler INT TERM ABRT ALRM USR1 USR2
+
+       while (( signal_received == 0 )) && read -r message; do
+               local topic
+
+               if ! topic=$(ipc_msg_get_topic "$message"); then
+                       log_warn "Dropping message without topic"
+                       continue
+               fi
+
+               if ! ipc_endpoint_publish "$endpoint" "$topic" "$message"; then
+                       log_error "Could not publish message for $topic on $endpoint"
+               fi
+       done
+
+       log_info "Closing endpoint $endpoint"
+       ipc_endpoint_close "$endpoint"
+
+       return 0
+}
+
+{
+       if ! . toolbox.sh; then
+               exit 1
+       fi
+
+       if ! include "log" "opt" "ipc"; then
+               exit 1
+       fi
+
+       main "$@"
+       exit "$?"
+}
diff --git a/utils/ipc-tap.sh b/utils/ipc-tap.sh
new file mode 100755 (executable)
index 0000000..45279b0
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+# ipc-tap.sh - Interceptor for toolbox IPC PubSub messages
+# Copyright (C) 2022 Matthias Kruk
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+add_topic() {
+       # local name="$1" # not needed
+       local value="$2"
+
+       # topics is inherited from main() via opt_parse()
+       topics+=("$value")
+       return 0
+}
+
+signal_handler() {
+       signal_received=1
+}
+
+tap_topics() {
+       local topics=("$@")
+
+       local endpoint
+       local topic
+       local -i err
+       local -ig signal_received
+
+       err=0
+       signal_received=0
+
+       if ! endpoint=$(ipc_endpoint_open); then
+               return 1
+       fi
+
+       log_info "Using endpoint $endpoint"
+       trap signal_handler INT HUP TERM ABRT ALRM USR1 USR2 PIPE
+
+       for topic in "${topics[@]}"; do
+               log_info "Subscribing $endpoint to $topic"
+
+               if ! ipc_endpoint_subscribe "$endpoint" "$topic"; then
+                       log_error "Could not subscribe $endpoint to $topic"
+                       err=1
+                       break
+               fi
+       done
+
+       if (( err == 0 )); then
+               log_info "Waiting for messages"
+
+               while (( signal_received == 0 )); do
+                       local message
+
+                       if message=$(ipc_endpoint_recv "$endpoint" 5); then
+                               printf '%s\n' "$message"
+                       fi
+               done
+       fi
+
+       log_info "Closing endpoint $endpoint"
+       ipc_endpoint_close "$endpoint"
+
+       return "$err"
+}
+
+main() {
+       local topics
+
+       topics=()
+
+       opt_add_arg "t" "topic" "rv" "" "A topic to tap into" "" add_topic
+
+       if ! opt_parse "$@"; then
+               return 1
+       fi
+
+       if ! tap_topics "${topics[@]}"; then
+               return 1
+       fi
+
+       return 0
+}
+
+{
+       if ! . toolbox.sh; then
+               exit 1
+       fi
+
+       if ! include "log" "opt" "ipc"; then
+               exit 1
+       fi
+
+       main "$@"
+       exit "$?"
+}