-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add connection prehook for scripted node traversal #432
Conversation
Example based on the initial feature request. Script: #!/bin/sh
set -e
function wait {
local timeout=$1 keyword=$2 line=""
while [[ $line != $keyword ]]; do read -t $timeout -r line; done
}
function print {
shift
echo "${@}\r"
}
#########################################
# The node traversal script starts here #
#########################################
print C K7LL-7
wait 10 Connected
print C K7LL-10
wait 10 Connected Usage: pat connect 'ax25:///K7LL-5?prehook=my-prehook.sh' |
... We should probably define a location for these scripts and append that to the spawned process' |
internal/prehook/prehook.go
Outdated
func Verify(file string) error { _, err := lookPath(file); return err } | ||
|
||
func lookPath(file string) (string, error) { | ||
// Look in our custom location first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works, but in an earlier comment you described trying to append the prehooks
dir to the process' PATH
. If that worked the way I assumed, our prehooks
dir would just be the first place LookPath
would explore, and you wouldn't have to do two checks. I'm guessing that didn't work out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that would be much easier. I thought the issue was that Go's standard library didn't provide a portable way of modifying $PATH. The syntax differs between Windows and linux/darwin.
.. However, while writing this comment I discovered os.PathListSeparator 😄 I'll give it another try! Thanks 🙂
log.Println("Running prehook...") | ||
script := prehook.Script{ | ||
File: exec, | ||
Args: url.Params["prehook-arg"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose I could just try this, but I can also ask you about your intent: url.Params["prehook-arg"]
gives back an array of args. If I have multiple args I need to pass to the script, do I make multiple URL params with the same key?
E.g. if I want to invoke the prehook script with:
my-prehook.sh --bool-arg --arg2=value
then I encode that in the URL as
ax25:///K7LL-5?prehook=my-prehook.sh&prehook-arg=--bool-arg&prehook-arg=--arg2=value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's correct 🙂 As an alternative we could consider a single argument with a separator. However, then we would also need to implement escaping in case the separator should be passed to the script.
@@ -33,6 +33,12 @@ path: | |||
params: | |||
?freq= Sets QSY frequency (ardop and ax25 only) | |||
?host= Overrides the host part of the path. Useful for serial-tnc to specify e.g. /dev/ttyS0. | |||
?prehook= Sets an executable middleware to run before the connection is handed over to the B2F protocol. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
High-level question: since we are making a connection pre-hook for initializing connections, does that now require that there's a post-hook for tearing the connection down cleanly? Maybe the proposed use case, AX.25 packet, is smart enough to tear down traversal links.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a very good question! 🤔
I would imagine that all connections would be teared down once one of the links are disconnected. Otherwise, you'd run the risk of dangling connections in case the dialer looses it's connection. But this is definitely something to investigate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could check to see if Winlink Express provides such a feature. If they don't, I would imagine it's not very common 😁
internal/prehook/prehook.go
Outdated
if err != nil { | ||
return err | ||
} | ||
cmd := exec.CommandContext(ctx, execPath, script.Args...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does the pre-hook script communicate its progress? Is exit code 0 the main/only way? I could see eventually expanding it to where the connection script can signal that the connection is ready, then Pat can signal when B2F is done and let the script tear down the connection. But I don't think that's necessary for v1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, exit code 0 == success. Any other exit code is assumed to be a failure, and the connection is closed with an error presented to the user.
I see your point. We could maybe use a signal like SIGCONT
for this, to keep stdio as transparent as possible. We would also need another mechanism to communicate that the connection is ready for B2F, as this is currently implemented by the child process exiting. But yes, maybe not necessary for v1.
Adds low-level connection prehook for all transports, implemented by spawning a user-defined process communicating with the remote station over stdio.
This enables scripted node traversal (#114) at the lowest possible level. To make it more practical and user-friendly, we need to add a layer on top. Not everyone is comfortable writing bash scripts/programs able to do this, so we need a simplified language with just enough flexibility to express the command/response sequences commonly used in packet node traversal.
TODO
pat connect help
)