-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from twelho/release-0.2
Iteration 0.2: socket activation, setup binary, instrumentation and better errors
- Loading branch information
Showing
17 changed files
with
1,023 additions
and
384 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "nm-proxy" | ||
version = "0.1.0" | ||
version = "0.2.0" | ||
edition = "2021" | ||
authors = ["Dennis Marttinen <[email protected]>"] | ||
description = "Native messaging proxy for Flatpak'ed browsers" | ||
|
@@ -19,6 +19,10 @@ path = "src/client/main.rs" | |
name = "daemon" | ||
path = "src/daemon/main.rs" | ||
|
||
[[bin]] | ||
name = "setup" | ||
path = "src/setup/main.rs" | ||
|
||
[profile.release] | ||
lto = true # Enable link-time optimizations | ||
strip = true # Strip symbols from the binary | ||
|
@@ -28,11 +32,14 @@ anyhow = "1.0.75" | |
byteorder = "1.5.0" | ||
expanduser = "1.2.2" | ||
libc = "0.2.149" | ||
log = "0.4.20" | ||
nix = { version = "0.27.1", features = ["signal"] } | ||
rust-ini = "0.19.0" | ||
sd-listen-fds = "0.2.0" | ||
serde = { version = "1.0.189", features = ["derive"] } | ||
serde_json = "1.0.107" | ||
tokio = { version = "1.33.0", features = ["full"] } | ||
tokio-fd = "0.3.0" | ||
tokio-util = "0.7.9" | ||
toml = "0.8.2" | ||
tracing-subscriber = "0.3.17" | ||
tracing = "0.1.40" | ||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,15 +4,68 @@ | |
|
||
## Architecture | ||
|
||
`nm-proxy` consists of a client and daemon binary. The client binary is executed by the Flatpak'ed browser, and forwards stdio through an exposed socket to the daemon on the host, which runs the native binary and forwards the socket traffic to its stdio. | ||
`nm-proxy` consists of a client, daemon, and setup binary. The client binary is executed by the Flatpak'ed browser, and forwards stdio through an exposed socket to the daemon on the host, which runs the native binary and forwards the socket traffic to its stdio. Sockets are handled by systemd to enable transparent daemon restarts without losing the inodes forwarded into the Flatpak namespaces. | ||
|
||
The daemon is intended to be run as a systemd user service, and will read its configuration as well as the [native manifests](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests) from `~/.config/nm-proxy` (configuration guidelines will be printed if missing). On launch, the daemon takes care of installing the client binary and manifest as well configuring the Flatpak environment for each specified browser. | ||
The daemon is intended to be run as a systemd user service, and will read its configuration as well as the [native manifests](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests) from `~/.config/nm-proxy` (guidelines will be printed if configuration is missing). The setup binary helps the daemon take care of installing the client binary and manifest as well configuring the Flatpak environment for each specified browser. | ||
|
||
The manifests themselves (`.json` files) must be supplied by the user. Here is the upstream manifest of the Plasma Integration extension, with which `nm-proxy` was tested during development: | ||
|
||
```json | ||
{ | ||
"name": "org.kde.plasma.browser_integration", | ||
"description": "Native connector for KDE Plasma", | ||
"path": "/usr/bin/plasma-browser-integration-host", | ||
"type": "stdio", | ||
"allowed_extensions": ["[email protected]"] | ||
} | ||
``` | ||
|
||
## Configuration | ||
|
||
```toml | ||
# nm-proxy 0.2.0 configuration file | ||
# | ||
# [daemon] | ||
# proxy_client = "/path/to/client" # Path to nm-proxy client binary | ||
# | ||
# [browsers.<name>] # Define configuration for browser <name> | ||
# app_id = "app.example.com" # Flatpak 3-part app ID | ||
# nmh_dir = ".<name>/native-messaging-hosts" # Native messaging host application directory | ||
# | ||
# Example configuration: | ||
|
||
[daemon] | ||
proxy_client = "~/path/to/client" | ||
|
||
[browsers.firefox] | ||
app_id = "org.mozilla.firefox" | ||
nmh_dir = ".mozilla/native-messaging-hosts" | ||
|
||
[browsers.librewolf] | ||
app_id = "io.gitlab.librewolf-community" | ||
nmh_dir = ".librewolf/native-messaging-hosts" | ||
|
||
[browsers.chromium] | ||
app_id = "org.chromium.Chromium" | ||
nmh_dir = ".config/chromium/NativeMessagingHosts" | ||
``` | ||
|
||
## Installation | ||
|
||
```shell | ||
$ ./install.sh | ||
Usage: ./install.sh <browser>... | ||
<browser> refers to the name of a browser entry in the configuration file of | ||
the nm-proxy daemon. Examples include "firefox", "librewolf", and "chromium". | ||
``` | ||
|
||
## Building | ||
|
||
The following builds all three binaries: | ||
|
||
```shell | ||
cargo build --bin client --release | ||
cargo build --bin daemon --release | ||
rustup target add x86_64-unknown-linux-musl | ||
cargo build --release | ||
``` | ||
|
||
## Acknowledgements | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/bin/sh -e | ||
|
||
if [ "$#" -eq 0 ]; then | ||
cat <<-EOF | ||
Usage: $0 <browser>... | ||
<browser> refers to the name of a browser entry in the configuration file of | ||
the nm-proxy daemon. Examples include "firefox", "librewolf", and "chromium". | ||
EOF | ||
|
||
exit 1 | ||
fi | ||
|
||
rustup target add x86_64-unknown-linux-musl | ||
cargo build --release | ||
|
||
DAEMON_PATH=$(readlink -f target/x86_64-unknown-linux-musl/release/daemon) | ||
SETUP_PATH=$(readlink -f target/x86_64-unknown-linux-musl/release/setup) | ||
|
||
cat >~/.config/systemd/user/nm-proxy-setup.service <<EOF | ||
[Unit] | ||
Description=nm-proxy setup helper | ||
[Service] | ||
#Environment=RUST_LOG=trace | ||
ExecStart="$SETUP_PATH" | ||
[Install] | ||
WantedBy=default.target | ||
EOF | ||
|
||
cat >~/.config/systemd/user/nm-proxy.service <<EOF | ||
[Unit] | ||
Description=nm-proxy daemon | ||
[Service] | ||
#Environment=RUST_LOG=trace | ||
ExecStart="$DAEMON_PATH" | ||
KillSignal=SIGINT | ||
NonBlocking=true | ||
EOF | ||
|
||
# The ListenStreams can't be touched after the socket services have been started without losing the FDs | ||
cat >~/.config/systemd/user/[email protected] <<EOF | ||
[Unit] | ||
Description=nm-proxy daemon sockets | ||
[Socket] | ||
Service=nm-proxy.service | ||
ListenStream=%t/nm-proxy-%I.socket | ||
FileDescriptorName=%I | ||
[Install] | ||
WantedBy=sockets.target | ||
EOF | ||
|
||
for browser in "$@"; do | ||
systemctl --user stop "nm-proxy@$browser.socket" | ||
done | ||
|
||
systemctl --user stop nm-proxy.service | ||
systemctl --user daemon-reload | ||
|
||
systemctl --user enable nm-proxy-setup.service | ||
systemctl --user start nm-proxy-setup.service | ||
|
||
for browser in "$@"; do | ||
systemctl --user enable "nm-proxy@$browser.socket" | ||
systemctl --user start "nm-proxy@$browser.socket" | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// (c) Dennis Marttinen 2023 | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
|
||
pub const SOCKET_PREFIX: &str = "nm-proxy-"; | ||
pub const SOCKET_SUFFIX: &str = ".socket"; | ||
pub const CONFIG_DIR: &str = "nm-proxy"; | ||
pub const CONFIG_FILE: &str = "config.toml"; | ||
pub const APP_MANIFEST_DIR: &str = "manifest"; | ||
pub const PROXY_CLIENT_BIN: &str = "nm-proxy-client"; | ||
pub const SETTINGS_FILE_NAME: &str = "nm-proxy-settings.toml"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// (c) Dennis Marttinen 2023 | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
|
||
use anyhow::{anyhow, bail, Result}; | ||
use std::env; | ||
|
||
pub mod settings; | ||
pub use settings::*; | ||
|
||
pub async fn parse_runtime_dir(context: &str) -> Result<String> { | ||
let mut args = env::args(); | ||
let invocation_path = args | ||
.next() | ||
.ok_or(anyhow!("Unable to acquire invocation path"))?; | ||
|
||
if let (Some(dir), None) = (args.next(), args.next()) { | ||
return Ok(dir); | ||
} | ||
|
||
bail!("Usage: {} <runtime-dir>\n{}", invocation_path, context); | ||
} |
Oops, something went wrong.