c8y-remote-access-plugin connection fails if installed in non-default location
Closed this issue · 2 comments
Describe the bug
It seems that when c8y-remote-access-plugin is called from the operation handler, if a custom --config-dir
is passed to the device, that this is not propagated when the child process is spawned via c8y-remote-access-plugin --child <connection_string>
.
When trying to connect to a give passthrough connection, the following error occurs:
% /opt/homebrew/bin/c8y-remote-access-plugin "--config-dir" "/opt/homebrew/etc/tedge" "530,rmi-macos,127.0.0.1,2812,33f21ccf-2eaa-4a1d-9216-2a414da1322a"
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: × Failed to spawn child process
╰─▶ No such file or directory (os error 2)
', crates/core/tedge/src/main.rs:50:58
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
It is unclear which file or directory does not exist as the error message does not supply a path.
To Reproduce
It is a bit tricky to reproduce as you have to use a non-standard installation, e.g. install thin-edge.io in any other folder other than /etc/tedge
, and /etc/tedge
must exist!
The instructions below assume you've used c8ylp before.
-
Install thin-edge.io in a custom setup (you'll have to use custom
tedge --config-dir init
for this) -
Manually create the
c8y_RemoteAccessConnect
operation handlerfile: /opt/homebrew/etc/tedge/operations/c8y/c8y_RemoteAccessConnect
[exec] command = "/opt/homebrew/bin/c8y-remote-access-plugin --config-dir /opt/homebrew/etc/tedge" topic = "c8y/s/ds" on_message = "530"
-
Create a Remote Access passthrough configuration for a local port on the device (e.g. port 22 if you have a ssh daemon running)
-
Try to connect to the Passthrough configuration using c8ylp
Expected behavior
The c8y-remote-access-plugin should work if installed in custom locations (e.g. not /etc/tedge
)
Screenshots
Environment (please complete the following information):
- OS [incl. version]:
MacOS
- Hardware [incl. revision]:
M1 (Apple Silicon)
- System-Architecture [e.g. result of "uname -a"]:
Darwin SAG-LJWQ4P62TY 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:12:58 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6000 arm64
- thin-edge.io version [e.g. 0.1.0]:
1.0.2~317+g1002ed6
Additional context
The following logic seems to be flawed. The spawn child should not have to re-read the operations file to work out how to launch itself, as the processes could be very different (say if someone overrides this)...instead the existing process should have all of the information it already needs (as the process is already running after all) without accessing the operation handler file.
async fn spawn_child(command: String, config_dir: &Utf8Path) -> miette::Result<()> {
Personally I would expected to see a reference to this function (or similar): https://doc.rust-lang.org/std/env/fn.current_exe.html#
For example (forgive my naive/limited Rust knowledge):
let exec_path = std::env::current_exe()
.into_diagnostic()
.with_context(|| {
format!("Could get current process executable")
})?;
let mut command = tokio::process::Command::new(exec_path)
.args(["--config-dir", config_dir.as_str()])
.arg("--child")
.arg(command)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.into_diagnostic()
.context("Failed to spawn child process")?;
With this change then the c8y-remote-access-plugin connection works:
QA has thoroughly checked the bug and here are the results:
- Test for ticket exists in the test suite.
- QA has tested the bug and it's not reproducable anymore