mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 02:18:47 +00:00
feat(gui-client): rename IPC service to Tunnel service (#9154)
The name IPC service is not very descriptive. By nature of being separate processes, we need to use IPC to communicate between them. The important thing is that the service process has control over the tunnel. Therefore, we rename everything to "Tunnel service". The only part that is not changed are historic changelog entries. Resolves: #9048
This commit is contained in:
@@ -17,7 +17,7 @@ pub struct DeviceId {
|
||||
/// e.g. `C:\ProgramData\dev.firezone.client/firezone-id.json` or
|
||||
/// `/var/lib/dev.firezone.client/config/firezone-id.json`.
|
||||
pub(crate) fn path() -> Result<PathBuf> {
|
||||
let path = crate::known_dirs::ipc_service_config()
|
||||
let path = crate::known_dirs::tunnel_service_config()
|
||||
.context("Failed to compute path for firezone-id file")?
|
||||
.join("firezone-id.json");
|
||||
Ok(path)
|
||||
@@ -53,7 +53,7 @@ pub fn get_or_create() -> Result<DeviceId> {
|
||||
fs::create_dir_all(dir).context("Failed to create dir for firezone-id")?;
|
||||
set_dir_permissions(dir).with_context(|| {
|
||||
format!(
|
||||
"Couldn't set permissions on IPC service config dir `{}`",
|
||||
"Couldn't set permissions on Tunnel service config dir `{}`",
|
||||
dir.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
@@ -50,7 +50,7 @@ impl DnsController {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Move DNS and network change listening to the IPC service, so this won't
|
||||
// TODO: Move DNS and network change listening to the Tunnel service, so this won't
|
||||
// need to be public.
|
||||
pub fn system_resolvers_for_gui() -> Result<Vec<IpAddr>> {
|
||||
system_resolvers(DnsControlMethod::default())
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
use anyhow::{Context as _, Result};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub use platform::{ipc_service_config, ipc_service_logs, logs, runtime, session, settings};
|
||||
pub use platform::{logs, runtime, session, settings, tunnel_service_config, tunnel_service_logs};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[path = "known_dirs/linux.rs"]
|
||||
@@ -24,9 +24,9 @@ pub mod platform;
|
||||
#[path = "known_dirs/windows.rs"]
|
||||
pub mod platform;
|
||||
|
||||
pub fn ipc_log_filter() -> Result<PathBuf> {
|
||||
Ok(ipc_service_config()
|
||||
.context("Failed to compute `ipc_service_config` directory")?
|
||||
pub fn tunnel_log_filter() -> Result<PathBuf> {
|
||||
Ok(tunnel_service_config()
|
||||
.context("Failed to compute `tunnel_service_config` directory")?
|
||||
.join("log-filter"))
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ mod tests {
|
||||
#[test]
|
||||
fn smoke() {
|
||||
for dir in [
|
||||
ipc_service_config(),
|
||||
ipc_service_logs(),
|
||||
tunnel_service_config(),
|
||||
tunnel_service_logs(),
|
||||
logs(),
|
||||
runtime(),
|
||||
session(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::BUNDLE_ID;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Path for IPC service config that the IPC service can write
|
||||
/// Path for Tunnel service config that the Tunnel service can write
|
||||
///
|
||||
/// All writes should use `atomicwrites`.
|
||||
///
|
||||
@@ -15,12 +15,12 @@ use std::path::PathBuf;
|
||||
///
|
||||
/// `config` to match how Windows has `config` and `data` both under `AppData/Local/$BUNDLE_ID`
|
||||
#[expect(clippy::unnecessary_wraps)] // Signature must match Windows
|
||||
pub fn ipc_service_config() -> Option<PathBuf> {
|
||||
pub fn tunnel_service_config() -> Option<PathBuf> {
|
||||
Some(PathBuf::from("/var/lib").join(BUNDLE_ID).join("config"))
|
||||
}
|
||||
|
||||
#[expect(clippy::unnecessary_wraps)] // Signature must match Windows
|
||||
pub fn ipc_service_logs() -> Option<PathBuf> {
|
||||
pub fn tunnel_service_logs() -> Option<PathBuf> {
|
||||
// TODO: This is magic, it must match the systemd file
|
||||
Some(PathBuf::from("/var/log").join(BUNDLE_ID))
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn ipc_service_config() -> Option<PathBuf> {
|
||||
pub fn tunnel_service_config() -> Option<PathBuf> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn ipc_service_logs() -> Option<PathBuf> {
|
||||
pub fn tunnel_service_logs() -> Option<PathBuf> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ pub fn app_local_data_dir() -> Result<PathBuf> {
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
/// Path for IPC service config that the IPC service can write
|
||||
/// Path for Tunnel service config that the Tunnel service can write
|
||||
///
|
||||
/// All writes should use `atomicwrites`.
|
||||
///
|
||||
/// On Windows, `C:/ProgramData/$BUNDLE_ID/config`
|
||||
pub fn ipc_service_config() -> Option<PathBuf> {
|
||||
pub fn tunnel_service_config() -> Option<PathBuf> {
|
||||
Some(
|
||||
get_known_folder_path(KnownFolder::ProgramData)?
|
||||
.join(BUNDLE_ID)
|
||||
@@ -28,7 +28,7 @@ pub fn ipc_service_config() -> Option<PathBuf> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ipc_service_logs() -> Option<PathBuf> {
|
||||
pub fn tunnel_service_logs() -> Option<PathBuf> {
|
||||
Some(
|
||||
get_known_folder_path(KnownFolder::ProgramData)?
|
||||
.join(BUNDLE_ID)
|
||||
|
||||
@@ -122,7 +122,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Messages that connlib can produce and send to the headless Client, IPC service, or GUI process.
|
||||
/// Messages that connlib can produce and send to the headless Client, Tunnel service, or GUI process.
|
||||
///
|
||||
/// i.e. callbacks
|
||||
// The names are CamelCase versions of the connlib callbacks.
|
||||
|
||||
@@ -57,9 +57,9 @@ rm "$INTERMEDIATE_DIR"/*.tar.gz
|
||||
# │ ├── lib
|
||||
# │ │ ├── systemd
|
||||
# │ │ │ └── system
|
||||
# │ │ │ └── firezone-client-ipc.service
|
||||
# │ │ │ └── firezone-client-tunnel.service
|
||||
# │ │ └── sysusers.d
|
||||
# │ │ └── firezone-client-ipc.conf
|
||||
# │ │ └── firezone-client-tunnel.conf
|
||||
# │ └── share
|
||||
# │ ├── applications
|
||||
# │ │ └── firezone-client-gui.desktop
|
||||
@@ -68,15 +68,15 @@ rm "$INTERMEDIATE_DIR"/*.tar.gz
|
||||
# └── debian-binary
|
||||
|
||||
# Add the scripts
|
||||
cp src-tauri/deb_files/postinst src-tauri/deb_files/prerm "$INTERMEDIATE_DIR/control/"
|
||||
cp src-tauri/deb_files/postinst src-tauri/deb_files/prerm src-tauri/deb_files/preinst "$INTERMEDIATE_DIR/control/"
|
||||
|
||||
# Add the IPC service
|
||||
cp ../target/release/firezone-client-ipc "$INTERMEDIATE_DIR/data/usr/bin/"
|
||||
# Add the Tunnel service
|
||||
cp ../target/release/firezone-client-tunnel "$INTERMEDIATE_DIR/data/usr/bin/"
|
||||
|
||||
pushd "$INTERMEDIATE_DIR"
|
||||
|
||||
# Rebuild the control tarball
|
||||
tar -C "control" -czf "control.tar.gz" control md5sums postinst prerm
|
||||
tar -C "control" -czf "control.tar.gz" control md5sums preinst postinst prerm
|
||||
|
||||
# Rebuild the data tarball
|
||||
tar -C "data" -czf "data.tar.gz" usr
|
||||
|
||||
@@ -36,15 +36,15 @@ If the client stops running while signed in, then the token may be stored in Win
|
||||
|
||||
## Linux Permissions
|
||||
|
||||
- [ ] The IPC service with `run-debug` can NOT run as a normal user
|
||||
- [ ] The IPC service with `run-debug` can run with `sudo`
|
||||
- [ ] The Tunnel service with `run-debug` can NOT run as a normal user
|
||||
- [ ] The Tunnel service with `run-debug` can run with `sudo`
|
||||
- [ ] The GUI can run as a normal user
|
||||
- [ ] The GUI can NOT run with `sudo`
|
||||
|
||||
## Windows Permissions
|
||||
|
||||
- [ ] The IPC service with `run-debug` can NOT run as a normal user
|
||||
- [ ] The IPC service with `run-debug` can run as admin
|
||||
- [ ] The Tunnel service with `run-debug` can NOT run as a normal user
|
||||
- [ ] The Tunnel service with `run-debug` can run as admin
|
||||
- [ ] The GUI can run as a normal user
|
||||
- [ ] The GUI can run as admin
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Unit]
|
||||
Description=Firezone Client
|
||||
Description=Firezone Client Tunnel Service
|
||||
After=systemd-resolved.service
|
||||
Wants=systemd-resolved.service
|
||||
|
||||
@@ -40,9 +40,9 @@ SystemCallFilter=@aio @basic-io @file-system @io-event @ipc @network-io @signal
|
||||
UMask=077
|
||||
|
||||
Environment="LOG_DIR=/var/log/dev.firezone.client"
|
||||
EnvironmentFile=-/etc/default/firezone-client-ipc
|
||||
EnvironmentFile=-/etc/default/firezone-client-tunnel
|
||||
|
||||
ExecStart=firezone-client-ipc run
|
||||
ExecStart=firezone-client-tunnel run
|
||||
Type=notify
|
||||
# Unfortunately we need root to control DNS
|
||||
User=root
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SERVICE_NAME="firezone-client-ipc"
|
||||
SERVICE_NAME="firezone-client-tunnel"
|
||||
|
||||
# Creates the system group `firezone-client`
|
||||
sudo systemd-sysusers
|
||||
|
||||
echo "Starting and enabling Firezone IPC service..."
|
||||
echo "Starting and enabling Firezone Tunnel service..."
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable "$SERVICE_NAME"
|
||||
sudo systemctl restart "$SERVICE_NAME"
|
||||
|
||||
10
rust/gui-client/src-tauri/deb_files/preinst
Executable file
10
rust/gui-client/src-tauri/deb_files/preinst
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
# Usage: dpkg will call this after installing our files
|
||||
# This must be idempotent
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
OLD_SERVICE_NAME="firezone-client-ipc"
|
||||
|
||||
sudo systemctl disable "$OLD_SERVICE_NAME" >/dev/null 2>&1 || true
|
||||
sudo systemctl stop "$OLD_SERVICE_NAME" >/dev/null 2>&1 || true
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SERVICE_NAME="firezone-client-ipc"
|
||||
SERVICE_NAME="firezone-client-tunnel"
|
||||
|
||||
sudo systemctl disable "$SERVICE_NAME"
|
||||
sudo systemctl stop "$SERVICE_NAME"
|
||||
|
||||
@@ -16,6 +16,11 @@ BuildRequires: systemd-rpm-macros
|
||||
|
||||
%prep
|
||||
|
||||
%pre
|
||||
# Stop and disable the old service. The service may no longer exist so we ensure this never fails.
|
||||
systemctl disable "$OLD_SERVICE_NAME" >/dev/null 2>&1 || true
|
||||
systemctl stop "$OLD_SERVICE_NAME" >/dev/null 2>&1 || true
|
||||
|
||||
%build
|
||||
|
||||
%install
|
||||
@@ -25,7 +30,7 @@ mkdir -p \
|
||||
|
||||
BINS="%{_topdir}/../../target/release"
|
||||
|
||||
cp "$BINS/firezone-client-ipc" "%{buildroot}/usr/bin/"
|
||||
cp "$BINS/firezone-client-tunnel" "%{buildroot}/usr/bin/"
|
||||
cp "$BINS/firezone-client-gui" "%{buildroot}/usr/lib/dev.firezone.client/"
|
||||
cp "%{_topdir}/../src-tauri/rpm_files/gui-shim.sh" "%{buildroot}/usr/bin/firezone-client-gui"
|
||||
|
||||
@@ -103,12 +108,12 @@ mkdir -p \
|
||||
"$ICONS/512x512/apps"
|
||||
|
||||
cp \
|
||||
"%{_topdir}/../src-tauri/deb_files/firezone-client-ipc.service" \
|
||||
"%{_topdir}/../src-tauri/deb_files/firezone-client-tunnel.service" \
|
||||
"%{buildroot}/usr/lib/systemd/system/"
|
||||
|
||||
cp \
|
||||
"%{_topdir}/../src-tauri/deb_files/sysusers.conf" \
|
||||
"%{buildroot}/usr/lib/sysusers.d/firezone-client-ipc.conf"
|
||||
"%{buildroot}/usr/lib/sysusers.d/firezone-client-tunnel.conf"
|
||||
|
||||
cp \
|
||||
"%{_topdir}/../src-tauri/rpm_files/firezone-client-gui.desktop" \
|
||||
@@ -127,7 +132,7 @@ cp \
|
||||
"$ICONS/512x512/apps/firezone-client-gui.png"
|
||||
|
||||
%files
|
||||
/usr/bin/firezone-client-ipc
|
||||
/usr/bin/firezone-client-tunnel
|
||||
/usr/bin/firezone-client-gui
|
||||
/usr/lib/dev.firezone.client/firezone-client-gui
|
||||
|
||||
@@ -163,8 +168,8 @@ cp \
|
||||
/usr/lib/dev.firezone.client/libX11.so.6
|
||||
/usr/lib/dev.firezone.client/libX11-xcb.so.1
|
||||
|
||||
/usr/lib/systemd/system/firezone-client-ipc.service
|
||||
/usr/lib/sysusers.d/firezone-client-ipc.conf
|
||||
/usr/lib/systemd/system/firezone-client-tunnel.service
|
||||
/usr/lib/sysusers.d/firezone-client-tunnel.conf
|
||||
|
||||
/usr/share/applications/firezone-client-gui.desktop
|
||||
/usr/share/icons/hicolor/32x32/apps/firezone-client-gui.png
|
||||
@@ -188,10 +193,10 @@ cp \
|
||||
%endif
|
||||
|
||||
%post
|
||||
%systemd_post firezone-client-ipc.service
|
||||
%systemd_post firezone-client-tunnel.service
|
||||
|
||||
%preun
|
||||
%systemd_preun firezone-client-ipc.service
|
||||
%systemd_preun firezone-client-tunnel.service
|
||||
|
||||
%postun
|
||||
%systemd_postun_with_restart firezone-client-ipc.service
|
||||
%systemd_postun_with_restart firezone-client-tunnel.service
|
||||
|
||||
@@ -60,7 +60,7 @@ pub struct Cli {
|
||||
|
||||
#[derive(clap::Subcommand)]
|
||||
enum Cmd {
|
||||
/// Needed to test the IPC service on aarch64 Windows,
|
||||
/// Needed to test the Tunnel service on aarch64 Windows,
|
||||
/// where the Tauri MSI bundler doesn't work yet
|
||||
Install,
|
||||
Run,
|
||||
@@ -80,7 +80,7 @@ mod tests {
|
||||
use clap::Parser;
|
||||
use std::path::PathBuf;
|
||||
|
||||
const EXE_NAME: &str = "firezone-client-ipc";
|
||||
const EXE_NAME: &str = "firezone-client-tunnel";
|
||||
|
||||
// Can't remember how Clap works sometimes
|
||||
// Also these are examples
|
||||
@@ -38,7 +38,7 @@ fn main() -> ExitCode {
|
||||
);
|
||||
|
||||
// Get the device ID before starting Tokio, so that all the worker threads will inherit the correct scope.
|
||||
// Technically this means we can fail to get the device ID on a newly-installed system, since the IPC service may not have fully started up when the GUI process reaches this point, but in practice it's unlikely.
|
||||
// Technically this means we can fail to get the device ID on a newly-installed system, since the Tunnel service may not have fully started up when the GUI process reaches this point, but in practice it's unlikely.
|
||||
if let Ok(id) = firezone_bin_shared::device_id::get() {
|
||||
Telemetry::set_firezone_id(id.id);
|
||||
}
|
||||
@@ -159,7 +159,9 @@ fn try_main(cli: Cli, rt: &tokio::runtime::Runtime, mut settings: AdvancedSettin
|
||||
.root_cause()
|
||||
.is::<firezone_gui_client::ipc::NotFound>()
|
||||
{
|
||||
show_error_dialog("Couldn't find Firezone IPC service. Is the service running?")?;
|
||||
show_error_dialog(
|
||||
"Couldn't find Firezone Tunnel service. Is the service running?",
|
||||
)?;
|
||||
return Err(anyhow);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ pub async fn clear_logs(path: &Path) -> Result<()> {
|
||||
Ok(x) => x,
|
||||
Err(error) => {
|
||||
if matches!(error.kind(), NotFound) {
|
||||
// In smoke tests, the IPC service runs in debug mode, so it won't write any logs to disk. If the IPC service's log dir doesn't exist, we shouldn't crash, it's correct to simply not delete the non-existent files
|
||||
// In smoke tests, the Tunnel service runs in debug mode, so it won't write any logs to disk. If the Tunnel service's log dir doesn't exist, we shouldn't crash, it's correct to simply not delete the non-existent files
|
||||
return Ok(());
|
||||
}
|
||||
// But any other error like permissions errors, should bubble.
|
||||
|
||||
@@ -86,7 +86,7 @@ pub trait GuiIntegration {
|
||||
pub enum ControllerRequest {
|
||||
/// The GUI wants us to use these settings in-memory, they've already been saved to disk
|
||||
ApplySettings(Box<AdvancedSettings>),
|
||||
/// Clear the GUI's logs and await the IPC service to clear its logs
|
||||
/// Clear the GUI's logs and await the Tunnel service to clear its logs
|
||||
ClearLogs(oneshot::Sender<Result<(), String>>),
|
||||
/// The same as the arguments to `client::logging::export_logs_to`
|
||||
ExportLogs {
|
||||
@@ -654,12 +654,12 @@ impl<I: GuiIntegration> Controller<I> {
|
||||
self.update_disabled_resources().await?;
|
||||
}
|
||||
service::ServerMsg::TerminatingGracefully => {
|
||||
tracing::info!("IPC service exited gracefully");
|
||||
tracing::info!("Tunnel service exited gracefully");
|
||||
self.integration
|
||||
.set_tray_icon(system_tray::icon_terminating());
|
||||
self.integration.show_notification(
|
||||
"Firezone disconnected",
|
||||
"The Firezone IPC service was shutdown, quitting GUI process.",
|
||||
"The Firezone Tunnel service was shutdown, quitting GUI process.",
|
||||
)?;
|
||||
|
||||
return Ok(ControlFlow::Break(()));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! A module for registering, catching, and parsing deep links that are sent over to the app's already-running instance
|
||||
|
||||
// The IPC parts use the same primitives as the IPC service, UDS on Linux
|
||||
// The IPC parts use the same primitives as the Tunnel service, UDS on Linux
|
||||
// and named pipes on Windows, so TODO de-dupe the IPC code
|
||||
|
||||
use crate::{
|
||||
|
||||
@@ -8,7 +8,7 @@ mod platform {
|
||||
|
||||
/// Returns true if all permissions are correct for the GUI to run
|
||||
///
|
||||
/// Everything that needs root / admin powers happens in the IPC services,
|
||||
/// Everything that needs root / admin powers happens in the Tunnel services,
|
||||
/// so for security and practicality reasons the GUIs must be non-root.
|
||||
/// (In Linux by default a root GUI app barely works at all)
|
||||
pub fn gui_check() -> Result<bool, Error> {
|
||||
|
||||
@@ -364,7 +364,7 @@ pub struct Icon {
|
||||
pub update_ready: bool,
|
||||
}
|
||||
|
||||
/// Generic icon for unusual terminating cases like if the IPC service stops running
|
||||
/// Generic icon for unusual terminating cases like if the Tunnel service stops running
|
||||
pub(crate) fn icon_terminating() -> Icon {
|
||||
Icon {
|
||||
base: IconBase::SignedOut,
|
||||
|
||||
@@ -29,7 +29,7 @@ pub(crate) mod platform;
|
||||
pub(crate) mod platform;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("Couldn't find IPC service `{0}`")]
|
||||
#[error("Couldn't find IPC socket `{0}`")]
|
||||
pub struct NotFound(String);
|
||||
|
||||
/// A name that both the server and client can use to find each other
|
||||
@@ -304,7 +304,7 @@ mod tests {
|
||||
|
||||
/// Replicate #5143
|
||||
///
|
||||
/// When the IPC service has disconnected from a GUI and loops over, sometimes
|
||||
/// When the Tunnel service has disconnected from a GUI and loops over, sometimes
|
||||
/// the named pipe is not ready. If our IPC code doesn't handle this right,
|
||||
/// this test will fail.
|
||||
#[tokio::test]
|
||||
|
||||
@@ -27,7 +27,7 @@ pub type ClientStream = UnixStream;
|
||||
/// On Windows `ClientStream` and `ServerStream` differ
|
||||
pub(crate) type ServerStream = UnixStream;
|
||||
|
||||
/// Connect to the IPC service
|
||||
/// Connect to the Tunnel service
|
||||
#[expect(clippy::wildcard_enum_match_arm)]
|
||||
pub async fn connect_to_socket(id: SocketId) -> Result<ClientStream> {
|
||||
let path = ipc_path(id);
|
||||
@@ -70,7 +70,7 @@ impl Server {
|
||||
std::fs::set_permissions(&sock_path, perms).context("Failed to set permissions on UDS")?;
|
||||
|
||||
// TODO: Change this to `notify_service_controller` and put it in
|
||||
// the same place in the IPC service's main loop as in the Headless Client.
|
||||
// the same place in the Tunnel service's main loop as in the Headless Client.
|
||||
sd_notify::notify(true, &[sd_notify::NotifyState::Ready])?;
|
||||
Ok(Self { listener, id })
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ impl Server {
|
||||
|
||||
// `&mut self` needed to match the Linux signature
|
||||
pub(crate) async fn next_client(&mut self) -> Result<ServerStream> {
|
||||
// Fixes #5143. In the IPC service, if we close the pipe and immediately re-open
|
||||
// Fixes #5143. In the Tunnel service, if we close the pipe and immediately re-open
|
||||
// it, Tokio may not get a chance to clean up the pipe. Yielding seems to fix
|
||||
// this in tests, but `yield_now` doesn't make any such guarantees, so
|
||||
// we also do a loop.
|
||||
|
||||
@@ -21,6 +21,6 @@ pub use clear_logs::clear_logs;
|
||||
|
||||
/// The Sentry "release" we are part of.
|
||||
///
|
||||
/// IPC service and GUI client are always bundled into a single release.
|
||||
/// Hence, we have a single constant for IPC service and GUI client.
|
||||
/// Tunnel service and GUI client are always bundled into a single release.
|
||||
/// Hence, we have a single constant for Tunnel service and GUI client.
|
||||
pub const RELEASE: &str = concat!("gui-client@", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
@@ -169,19 +169,22 @@ pub fn setup_gui(directives: &str) -> Result<Handles> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Starts logging for the production IPC service
|
||||
/// Starts logging for the production Tunnel service
|
||||
///
|
||||
/// Returns: A `Handle` that must be kept alive. Dropping it stops logging
|
||||
/// and flushes the log file.
|
||||
pub fn setup_ipc(
|
||||
pub fn setup_tunnel(
|
||||
log_path: Option<PathBuf>,
|
||||
) -> Result<(
|
||||
firezone_logging::file::Handle,
|
||||
firezone_logging::FilterReloadHandle,
|
||||
)> {
|
||||
// If `log_dir` is Some, use that. Else call `ipc_service_logs`
|
||||
// If `log_dir` is Some, use that. Else call `tunnel_service_logs`
|
||||
let log_path = log_path.map_or_else(
|
||||
|| known_dirs::ipc_service_logs().context("Should be able to compute IPC service logs dir"),
|
||||
|| {
|
||||
known_dirs::tunnel_service_logs()
|
||||
.context("Should be able to compute Tunnel service logs dir")
|
||||
},
|
||||
Ok,
|
||||
)?;
|
||||
std::fs::create_dir_all(&log_path)
|
||||
@@ -211,7 +214,7 @@ pub fn setup_ipc(
|
||||
?directives,
|
||||
system_uptime = firezone_bin_shared::uptime::get().map(tracing::field::debug),
|
||||
log_path = %log_path.display(),
|
||||
"`ipc-service` started logging"
|
||||
"`tunnel service` started logging"
|
||||
);
|
||||
|
||||
Ok((file_handle, file_reloader.merge(stdout_reloader)))
|
||||
@@ -229,13 +232,13 @@ pub fn setup_stdout() -> Result<FilterReloadHandle> {
|
||||
|
||||
Ok(reloader)
|
||||
}
|
||||
/// Reads the log filter for the IPC service or for debug commands
|
||||
/// Reads the log filter for the Tunnel service or for debug commands
|
||||
///
|
||||
/// e.g. `info`
|
||||
///
|
||||
/// Reads from:
|
||||
/// 1. `RUST_LOG` env var
|
||||
/// 2. `known_dirs::ipc_log_filter()` file
|
||||
/// 2. `known_dirs::tunnel_log_filter()` file
|
||||
/// 3. Hard-coded default `SERVICE_RUST_LOG`
|
||||
///
|
||||
/// Errors if something is badly wrong, e.g. the directory for the config file
|
||||
@@ -250,8 +253,9 @@ pub(crate) fn get_log_filter() -> Result<String> {
|
||||
return Ok(filter);
|
||||
}
|
||||
|
||||
if let Ok(filter) = std::fs::read_to_string(firezone_bin_shared::known_dirs::ipc_log_filter()?)
|
||||
.map(|s| s.trim().to_string())
|
||||
if let Ok(filter) =
|
||||
std::fs::read_to_string(firezone_bin_shared::known_dirs::tunnel_log_filter()?)
|
||||
.map(|s| s.trim().to_string())
|
||||
{
|
||||
return Ok(filter);
|
||||
}
|
||||
@@ -332,7 +336,7 @@ fn add_dir_to_zip(
|
||||
Ok(x) => x,
|
||||
Err(error) => {
|
||||
if matches!(error.kind(), NotFound) {
|
||||
// In smoke tests, the IPC service runs in debug mode, so it won't write any logs to disk. If the IPC service's log dir doesn't exist, we shouldn't crash, it's correct to simply not add any files to the zip
|
||||
// In smoke tests, the Tunnel service runs in debug mode, so it won't write any logs to disk. If the Tunnel service's log dir doesn't exist, we shouldn't crash, it's correct to simply not add any files to the zip
|
||||
return Ok(());
|
||||
}
|
||||
// But any other error like permissions errors, should bubble.
|
||||
@@ -384,7 +388,8 @@ async fn count_one_dir(path: &Path) -> Result<FileCount> {
|
||||
fn log_paths() -> Result<Vec<LogPath>> {
|
||||
Ok(vec![
|
||||
LogPath {
|
||||
src: known_dirs::ipc_service_logs().context("Can't compute IPC service logs dir")?,
|
||||
src: known_dirs::tunnel_service_logs()
|
||||
.context("Can't compute Tunnel service logs dir")?,
|
||||
dst: PathBuf::from("connlib"),
|
||||
},
|
||||
LogPath {
|
||||
|
||||
@@ -64,11 +64,11 @@ pub enum ClientMsg {
|
||||
},
|
||||
}
|
||||
|
||||
/// Messages that end up in the GUI, either forwarded from connlib or from the IPC service.
|
||||
/// Messages that end up in the GUI, either forwarded from connlib or from the Tunnel service.
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, strum::Display)]
|
||||
pub enum ServerMsg {
|
||||
Hello,
|
||||
/// The IPC service finished clearing its log dir.
|
||||
/// The Tunnel service finished clearing its log dir.
|
||||
ClearedLogs(Result<(), String>),
|
||||
ConnectResult(Result<(), ConnectError>),
|
||||
DisconnectedGracefully,
|
||||
@@ -77,7 +77,7 @@ pub enum ServerMsg {
|
||||
is_authentication_error: bool,
|
||||
},
|
||||
OnUpdateResources(Vec<ResourceView>),
|
||||
/// The IPC service is terminating, maybe due to a software update
|
||||
/// The Tunnel service is terminating, maybe due to a software update
|
||||
///
|
||||
/// This is a hint that the Client should exit with a message like,
|
||||
/// "Firezone is updating, please restart the GUI" instead of an error like,
|
||||
@@ -108,7 +108,7 @@ impl From<anyhow::Error> for ConnectError {
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the IPC service and terminate gracefully if we catch a terminate signal
|
||||
/// Run the Tunnel service and terminate gracefully if we catch a terminate signal
|
||||
///
|
||||
/// If an IPC client is connected when we catch a terminate signal, we send the
|
||||
/// client a hint about that before we exit.
|
||||
@@ -118,7 +118,7 @@ async fn ipc_listen(
|
||||
signals: &mut signals::Terminate,
|
||||
telemetry: &mut Telemetry,
|
||||
) -> Result<()> {
|
||||
// Create the device ID and IPC service config dir if needed
|
||||
// Create the device ID and Tunnel service config dir if needed
|
||||
// This also gives the GUI a safe place to put the log filter config
|
||||
let firezone_id = device_id::get_or_create()
|
||||
.context("Failed to read / create device ID")?
|
||||
@@ -238,7 +238,7 @@ impl<'a> Handler<'a> {
|
||||
|
||||
/// Run the event loop to communicate with an IPC client.
|
||||
///
|
||||
/// If the IPC service needs to terminate, we catch that from `signals` and send
|
||||
/// If the Tunnel service needs to terminate, we catch that from `signals` and send
|
||||
/// the client a hint to shut itself down gracefully.
|
||||
///
|
||||
/// The return type is infallible so that we only give up on an IPC client explicitly
|
||||
@@ -360,7 +360,7 @@ impl<'a> Handler<'a> {
|
||||
match msg {
|
||||
ClientMsg::ClearLogs => {
|
||||
let result = crate::clear_logs(
|
||||
&firezone_bin_shared::known_dirs::ipc_service_logs()
|
||||
&firezone_bin_shared::known_dirs::tunnel_service_logs()
|
||||
.context("Can't compute logs dir")?,
|
||||
)
|
||||
.await;
|
||||
@@ -385,7 +385,7 @@ impl<'a> Handler<'a> {
|
||||
ClientMsg::ApplyLogFilter { directives } => {
|
||||
self.log_filter_reloader.reload(&directives)?;
|
||||
|
||||
let path = known_dirs::ipc_log_filter()?;
|
||||
let path = known_dirs::tunnel_log_filter()?;
|
||||
|
||||
if let Err(e) = AtomicFile::new(&path, OverwriteBehavior::AllowOverwrite)
|
||||
.write(|f| f.write_all(directives.as_bytes()))
|
||||
@@ -531,7 +531,7 @@ pub fn run_debug(dns_control: DnsControlMethod) -> Result<()> {
|
||||
system_uptime_seconds = firezone_bin_shared::uptime::get().map(|dur| dur.as_secs()),
|
||||
);
|
||||
if !elevation_check()? {
|
||||
bail!("IPC service failed its elevation check, try running as admin / root");
|
||||
bail!("Tunnel service failed its elevation check, try running as admin / root");
|
||||
}
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
@@ -548,7 +548,7 @@ pub fn run_debug(dns_control: DnsControlMethod) -> Result<()> {
|
||||
))
|
||||
.inspect(|_| rt.block_on(telemetry.stop()))
|
||||
.inspect_err(|e| {
|
||||
tracing::error!("IPC service failed: {e:#}");
|
||||
tracing::error!("Tunnel service failed: {e:#}");
|
||||
|
||||
rt.block_on(telemetry.stop_on_crash())
|
||||
})
|
||||
@@ -565,7 +565,7 @@ pub fn run_smoke_test() -> Result<()> {
|
||||
|
||||
let log_filter_reloader = crate::logging::setup_stdout()?;
|
||||
if !elevation_check()? {
|
||||
bail!("IPC service failed its elevation check, try running as admin / root");
|
||||
bail!("Tunnel service failed its elevation check, try running as admin / root");
|
||||
}
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
@@ -574,7 +574,7 @@ pub fn run_smoke_test() -> Result<()> {
|
||||
let mut dns_controller = DnsController {
|
||||
dns_control_method: Default::default(),
|
||||
};
|
||||
// Deactivate Firezone DNS control in case the system or IPC service crashed
|
||||
// Deactivate Firezone DNS control in case the system or Tunnel service crashed
|
||||
// and we need to recover. <https://github.com/firezone/firezone/issues/4899>
|
||||
dns_controller.deactivate()?;
|
||||
let mut signals = signals::Terminate::new()?;
|
||||
|
||||
@@ -9,9 +9,9 @@ use firezone_telemetry::Telemetry;
|
||||
///
|
||||
/// Linux uses the CLI args from here, Windows does not
|
||||
pub fn run(log_dir: Option<PathBuf>, dns_control: DnsControlMethod) -> Result<()> {
|
||||
let (_handle, log_filter_reloader) = crate::logging::setup_ipc(log_dir)?;
|
||||
let (_handle, log_filter_reloader) = crate::logging::setup_tunnel(log_dir)?;
|
||||
if !elevation_check()? {
|
||||
bail!("IPC service failed its elevation check, try running as admin / root");
|
||||
bail!("Tunnel service failed its elevation check, try running as admin / root");
|
||||
}
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
@@ -28,13 +28,13 @@ pub fn run(log_dir: Option<PathBuf>, dns_control: DnsControlMethod) -> Result<()
|
||||
))
|
||||
.inspect(|_| rt.block_on(telemetry.stop()))
|
||||
.inspect_err(|e| {
|
||||
tracing::error!("IPC service failed: {e:#}");
|
||||
tracing::error!("Tunnel service failed: {e:#}");
|
||||
|
||||
rt.block_on(telemetry.stop_on_crash())
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns true if the IPC service can run properly
|
||||
/// Returns true if the Tunnel service can run properly
|
||||
// Fallible on Windows
|
||||
#[expect(clippy::unnecessary_wraps)]
|
||||
pub fn elevation_check() -> Result<bool> {
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::path::PathBuf;
|
||||
|
||||
pub fn run(log_dir: Option<PathBuf>, _dns_control: DnsControlMethod) -> Result<()> {
|
||||
// We call this here to avoid a dead-code warning.
|
||||
let (_handle, _log_filter_reloader) = crate::logging::setup_ipc(log_dir)?;
|
||||
let (_handle, _log_filter_reloader) = crate::logging::setup_tunnel(log_dir)?;
|
||||
|
||||
bail!("not implemented")
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ use windows_service::{
|
||||
const SERVICE_NAME: &str = "firezone_client_ipc";
|
||||
const SERVICE_TYPE: ServiceType = ServiceType::OWN_PROCESS;
|
||||
|
||||
/// Returns true if the IPC service can run properly
|
||||
/// Returns true if the Tunnel service can run properly
|
||||
pub fn elevation_check() -> Result<bool> {
|
||||
let token = ProcessToken::our_process().context("Failed to get process token")?;
|
||||
let elevated = token
|
||||
@@ -152,10 +152,10 @@ pub fn install() -> Result<()> {
|
||||
let manager_access = ServiceManagerAccess::CONNECT | ServiceManagerAccess::CREATE_SERVICE;
|
||||
let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?;
|
||||
|
||||
let name = "FirezoneClientIpcServiceDebug";
|
||||
let name = "FirezoneClientTunnelServiceDebug";
|
||||
|
||||
// Un-install existing one first if needed
|
||||
if let Err(e) = uninstall_ipc_service(&service_manager, name)
|
||||
if let Err(e) = uninstall_tunnel_service(&service_manager, name)
|
||||
.with_context(|| format!("Failed to uninstall `{name}`"))
|
||||
{
|
||||
tracing::debug!("{e:#}");
|
||||
@@ -164,7 +164,7 @@ pub fn install() -> Result<()> {
|
||||
let executable_path = std::env::current_exe()?;
|
||||
let service_info = ServiceInfo {
|
||||
name: OsString::from(name),
|
||||
display_name: OsString::from("Firezone Client IPC (Debug)"),
|
||||
display_name: OsString::from("Firezone Tunnel Service (Debug)"),
|
||||
service_type: ServiceType::OWN_PROCESS,
|
||||
start_type: ServiceStartType::AutoStart,
|
||||
error_control: ServiceErrorControl::Normal,
|
||||
@@ -179,7 +179,10 @@ pub fn install() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn uninstall_ipc_service(service_manager: &ServiceManager, name: impl AsRef<OsStr>) -> Result<()> {
|
||||
fn uninstall_tunnel_service(
|
||||
service_manager: &ServiceManager,
|
||||
name: impl AsRef<OsStr>,
|
||||
) -> Result<()> {
|
||||
let service_access = ServiceAccess::DELETE;
|
||||
let service = service_manager.open_service(name, service_access)?;
|
||||
service.delete()?;
|
||||
@@ -201,7 +204,7 @@ fn service_run(arguments: Vec<OsString>) {
|
||||
// `arguments` doesn't seem to work right when running as a Windows service
|
||||
// (even though it's meant for that) so just use the default log dir.
|
||||
let (handle, log_filter_reloader) =
|
||||
crate::logging::setup_ipc(None).expect("Should be able to set up logging");
|
||||
crate::logging::setup_tunnel(None).expect("Should be able to set up logging");
|
||||
if let Err(error) = fallible_service_run(arguments, handle, log_filter_reloader) {
|
||||
tracing::error!("`fallible_windows_service_run` returned an error: {error:#}");
|
||||
}
|
||||
@@ -219,7 +222,7 @@ fn fallible_service_run(
|
||||
) -> Result<()> {
|
||||
tracing::info!(?arguments, "fallible_windows_service_run");
|
||||
if !elevation_check()? {
|
||||
bail!("IPC service failed its elevation check, try running as admin / root");
|
||||
bail!("Tunnel service failed its elevation check, try running as admin / root");
|
||||
}
|
||||
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
@@ -289,7 +292,7 @@ fn fallible_service_run(
|
||||
))
|
||||
.inspect(|_| rt.block_on(telemetry.stop()))
|
||||
.inspect_err(|e| {
|
||||
tracing::error!("IPC service failed: {e:#}");
|
||||
tracing::error!("Tunnel service failed: {e:#}");
|
||||
|
||||
rt.block_on(telemetry.stop_on_crash())
|
||||
});
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
"linux": {
|
||||
"deb": {
|
||||
"files": {
|
||||
"/usr/lib/systemd/system/firezone-client-ipc.service": "./deb_files/firezone-client-ipc.service",
|
||||
"/usr/lib/sysusers.d/firezone-client-ipc.conf": "./deb_files/sysusers.conf"
|
||||
"/usr/lib/systemd/system/firezone-client-tunnel.service": "./deb_files/firezone-client-tunnel.service",
|
||||
"/usr/lib/sysusers.d/firezone-client-tunnel.conf": "./deb_files/sysusers.conf"
|
||||
},
|
||||
"desktopTemplate": "./deb_files/firezone-client-gui.desktop"
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
"windows": {
|
||||
"wix": {
|
||||
"bannerPath": "./win_files/banner.png",
|
||||
"componentRefs": ["FirezoneClientIpcService"],
|
||||
"componentRefs": ["RemoveOldFirezoneService", "FirezoneClientTunnelService"],
|
||||
"dialogImagePath": "./win_files/install_dialog.png",
|
||||
"fragmentPaths": ["./win_files/service.wxs"],
|
||||
"template": "./win_files/main.wxs"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"build": {
|
||||
"beforeBundleCommand": "bash -c '../../scripts/build/sign.sh ../target/release/Firezone.exe ../target/release/firezone-client-ipc.exe'"
|
||||
"beforeBundleCommand": "bash -c '../../scripts/build/sign.sh ../target/release/Firezone.exe ../target/release/firezone-client-tunnel.exe'"
|
||||
},
|
||||
"mainBinaryName": "Firezone",
|
||||
"productName": "Firezone"
|
||||
|
||||
@@ -345,6 +345,17 @@ component.
|
||||
</InstallExecuteSequence>
|
||||
{{/if}}
|
||||
|
||||
<!-- Hack for removing duplicate service binary. Can be removed in later versions when most/all users have upgraded to a newer version of Firezone. -->
|
||||
<CustomAction Id="DeleteOldServiceFile"
|
||||
Directory="INSTALLDIR"
|
||||
Execute="deferred"
|
||||
Return="ignore"
|
||||
ExeCommand="powershell.exe -NoProfile -WindowStyle Hidden -Command "Remove-Item -Path '[INSTALLDIR]firezone-client-ipc.exe' -Force -ErrorAction SilentlyContinue"" />
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="DeleteOldServiceFile" Before="InstallFinalize">NOT Installed</Custom>
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="LaunchApplication" After="InstallFinalize">AUTOLAUNCHAPP AND NOT Installed</Custom>
|
||||
</InstallExecuteSequence>
|
||||
|
||||
@@ -2,21 +2,51 @@
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Fragment>
|
||||
<DirectoryRef Id="INSTALLDIR">
|
||||
<Component Id="FirezoneClientIpcService" Guid="a8092ff9-30fa-48bb-9b2d-45fe39d16c66">
|
||||
<File Id="FirezoneClientIpcServiceExe" Name="firezone-client-ipc.exe" Source="../../firezone-client-ipc.exe" KeyPath="yes" />
|
||||
<ServiceInstall
|
||||
Id="FirezoneClientServiceInstaller"
|
||||
Arguments="run"
|
||||
Type="ownProcess"
|
||||
Vital="yes"
|
||||
Name="FirezoneClientIpcService"
|
||||
DisplayName="Firezone Client IPC"
|
||||
Start="auto"
|
||||
Account="LocalSystem"
|
||||
ErrorControl="normal"
|
||||
Interactive="no">
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="FirezoneClientServiceControl" Start="install" Stop="both" Remove="both" Name="FirezoneClientIpcService" Wait="yes" />
|
||||
<Component Id="RemoveOldFirezoneService" Guid="2cfa312f-9a0a-4a3c-bfe8-c7304f69a467">
|
||||
<ServiceControl Id="RemoveOldFirezoneService" Name="FirezoneClientIpcService"
|
||||
Stop="both" Remove="both" Wait="yes" />
|
||||
<ServiceControl Id="RemoveOldFirezoneDebugService" Name="FirezoneClientIpcServiceDebug"
|
||||
Stop="both" Remove="both" Wait="yes" />
|
||||
|
||||
<!--
|
||||
Hack to make the rename of the service work:
|
||||
|
||||
The Windows installer wants to close already running applications and it detects those by checking
|
||||
whether the file is in use.
|
||||
If we rename the service file, it the new name will not be in used and therefore, Windows won't
|
||||
shut it down prior to installation.
|
||||
|
||||
It will however try to shut the GUI process down by sending WM_CLOSE. Firezone typically doesn't
|
||||
have any Windows open and therefore,
|
||||
WM_CLOSE does nothing and the installer hangs forever trying to close our program.
|
||||
|
||||
To fix this, we install the service binary under the old AND new name to force the installer to
|
||||
shut down the service.
|
||||
The duplicate file is removed as part of a custom action in `main.wxs`
|
||||
-->
|
||||
<File Id="FirezoneClientIpcServiceExe" Name="firezone-client-ipc.exe"
|
||||
Source="../../firezone-client-tunnel.exe" KeyPath="yes" />
|
||||
</Component>
|
||||
|
||||
<Component Id="FirezoneClientTunnelService" Guid="bd082abf-bd17-4e6f-aed1-4126a8596ecd">
|
||||
<File Id="FirezoneClientTunnelServiceExe" Name="firezone-client-tunnel.exe"
|
||||
Source="../../firezone-client-tunnel.exe" KeyPath="yes" />
|
||||
|
||||
<ServiceInstall
|
||||
Id="FirezoneClientTunnelServiceInstaller"
|
||||
Arguments="run"
|
||||
Type="ownProcess"
|
||||
Vital="yes"
|
||||
Name="FirezoneClientTunnelService"
|
||||
DisplayName="Firezone Tunnel Service"
|
||||
Start="auto"
|
||||
Account="LocalSystem"
|
||||
ErrorControl="normal"
|
||||
Interactive="no">
|
||||
</ServiceInstall>
|
||||
|
||||
<ServiceControl Id="FirezoneClientTunnelServiceControl" Start="install" Stop="both"
|
||||
Remove="both" Name="FirezoneClientTunnelService" Wait="yes" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
</Fragment>
|
||||
|
||||
@@ -157,7 +157,7 @@ fn main() -> Result<()> {
|
||||
assert!(std::env::var(TOKEN_ENV_KEY).is_err());
|
||||
|
||||
// TODO: This might have the same issue with fatal errors not getting logged
|
||||
// as addressed for the IPC service in PR #5216
|
||||
// as addressed for the Tunnel service in PR #5216
|
||||
let (layer, _handle) = cli
|
||||
.log_dir
|
||||
.as_deref()
|
||||
@@ -169,7 +169,7 @@ fn main() -> Result<()> {
|
||||
// in case a previous run of Firezone left DNS control on and messed anything up.
|
||||
let dns_control_method = cli.dns_control;
|
||||
let mut dns_controller = DnsController { dns_control_method };
|
||||
// Deactivate Firezone DNS control in case the system or IPC service crashed
|
||||
// Deactivate Firezone DNS control in case the system or Tunnel service crashed
|
||||
// and we need to recover. <https://github.com/firezone/firezone/issues/4899>
|
||||
dns_controller.deactivate()?;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Implementation of headless Client and IPC service for Windows
|
||||
//! Implementation of headless Client and Tunnel service for Windows
|
||||
//!
|
||||
//! Try not to panic in the IPC service. Windows doesn't consider the
|
||||
//! Try not to panic in the Tunnel service. Windows doesn't consider the
|
||||
//! service to be stopped even if its only process ends, for some reason.
|
||||
//! We must tell Windows explicitly when our service is stopping.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Invoke with `cargo run --bin gui-smoke-test`
|
||||
//
|
||||
// Starts up the IPC service and GUI app and lets them run for a bit
|
||||
// Starts up the Tunnel service and GUI app and lets them run for a bit
|
||||
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
use clap::Parser;
|
||||
@@ -14,7 +14,7 @@ use subprocess::Exec;
|
||||
const FZ_GROUP: &str = "firezone-client";
|
||||
|
||||
const GUI_NAME: &str = "firezone-gui-client";
|
||||
const IPC_NAME: &str = "firezone-client-ipc";
|
||||
const TUNNEL_NAME: &str = "firezone-client-tunnel";
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
const EXE_EXTENSION: &str = "";
|
||||
@@ -40,22 +40,22 @@ fn main() -> Result<()> {
|
||||
dump_syms().context("Failed to run `dump_syms`")?;
|
||||
|
||||
// Run normal smoke test
|
||||
let mut ipc_service = ipc_service_command().arg("run-smoke-test").popen()?;
|
||||
let mut ipc_service = tunnel_service_command().arg("run-smoke-test").popen()?;
|
||||
let mut gui = app
|
||||
.gui_command(&["smoke-test"])? // Disable deep links because they don't work in the headless CI environment
|
||||
.popen()?;
|
||||
|
||||
gui.wait()?.fz_exit_ok().context("GUI process")?;
|
||||
|
||||
ipc_service.wait()?.fz_exit_ok().context("IPC service")?;
|
||||
ipc_service.wait()?.fz_exit_ok().context("Tunnel service")?;
|
||||
|
||||
// Force the GUI to crash
|
||||
let mut ipc_service = ipc_service_command().arg("run-smoke-test").popen()?;
|
||||
let mut ipc_service = tunnel_service_command().arg("run-smoke-test").popen()?;
|
||||
let mut gui = app.gui_command(&["--crash"])?.popen()?;
|
||||
|
||||
// Ignore exit status here since we asked the GUI to crash on purpose
|
||||
gui.wait()?;
|
||||
ipc_service.wait()?.fz_exit_ok().context("IPC service")?;
|
||||
ipc_service.wait()?.fz_exit_ok().context("Tunnel service")?;
|
||||
|
||||
if cli.manual_tests {
|
||||
manual_tests(&app)?;
|
||||
@@ -70,12 +70,12 @@ fn manual_tests(app: &App) -> Result<()> {
|
||||
.popen()?
|
||||
.wait()?;
|
||||
|
||||
let mut ipc_service = ipc_service_command().arg("run-smoke-test").popen()?;
|
||||
let mut ipc_service = tunnel_service_command().arg("run-smoke-test").popen()?;
|
||||
let mut gui = app.gui_command(&["--quit-after", "10"])?.popen()?;
|
||||
|
||||
// Expect exit codes of 0
|
||||
gui.wait()?.fz_exit_ok().context("GUI process")?;
|
||||
ipc_service.wait()?.fz_exit_ok().context("IPC service")?;
|
||||
ipc_service.wait()?.fz_exit_ok().context("Tunnel service")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -184,7 +184,7 @@ fn debug_db_path() -> PathBuf {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn ipc_service_command() -> Exec {
|
||||
fn tunnel_service_command() -> Exec {
|
||||
Exec::cmd("sudo").args(&[
|
||||
"--preserve-env",
|
||||
"runuser", // The `runuser` looks redundant but CI will complain if we use `sudo` directly, not sure why
|
||||
@@ -193,15 +193,15 @@ fn ipc_service_command() -> Exec {
|
||||
"--group",
|
||||
"firezone-client",
|
||||
"--whitelist-environment=RUST_LOG",
|
||||
ipc_path()
|
||||
tunnel_path()
|
||||
.to_str()
|
||||
.expect("IPC binary path should be valid Unicode"),
|
||||
])
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn ipc_service_command() -> Exec {
|
||||
Exec::cmd(ipc_path())
|
||||
fn tunnel_service_command() -> Exec {
|
||||
Exec::cmd(tunnel_path())
|
||||
}
|
||||
|
||||
// `ExitStatus::exit_ok` is nightly, so we add an equivalent here
|
||||
@@ -225,10 +225,10 @@ fn gui_path() -> PathBuf {
|
||||
.with_extension(EXE_EXTENSION)
|
||||
}
|
||||
|
||||
fn ipc_path() -> PathBuf {
|
||||
fn tunnel_path() -> PathBuf {
|
||||
Path::new("target")
|
||||
.join("debug")
|
||||
.join(IPC_NAME)
|
||||
.join(TUNNEL_NAME)
|
||||
.with_extension(EXE_EXTENSION)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
SERVICE_NAME=firezone-client-ipc
|
||||
SERVICE_NAME=firezone-client-tunnel
|
||||
|
||||
function debug_exit() {
|
||||
systemctl status "$SERVICE_NAME"
|
||||
@@ -21,12 +21,12 @@ dpkg --listfiles firezone-client-gui
|
||||
dpkg --info "$DEB_PATH"
|
||||
|
||||
# Confirm that both binaries and at least one icon were installed
|
||||
which firezone-client-gui firezone-client-ipc
|
||||
which firezone-client-gui firezone-client-tunnel
|
||||
stat /usr/share/icons/hicolor/512x512/apps/firezone-client-gui.png
|
||||
|
||||
# Make sure the binary got built, packaged, and installed, and at least
|
||||
# knows its own name
|
||||
firezone-client-gui --help | grep "Usage: firezone-client-gui"
|
||||
|
||||
# Make sure the IPC service is running
|
||||
# Make sure the Tunnel service is running
|
||||
systemctl status "$SERVICE_NAME" || debug_exit
|
||||
|
||||
@@ -5,5 +5,5 @@ set -euox pipefail
|
||||
msiexec //i "$BINARY_DEST_PATH.msi" //log install.log //qn
|
||||
# For debugging
|
||||
cat install.log
|
||||
# Make sure the IPC service is running
|
||||
sc query FirezoneClientIpcService | grep RUNNING
|
||||
# Make sure the Tunnel service is running
|
||||
sc query FirezoneClientTunnelService | grep RUNNING
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
|
||||
BINARY_NAME=firezone-client-ipc
|
||||
BINARY_NAME=firezone-client-tunnel
|
||||
FZ_GROUP="firezone-client"
|
||||
SERVICE_NAME=firezone-client-ipc
|
||||
SERVICE_NAME=firezone-client-tunnel
|
||||
SOCKET=/run/dev.firezone.client/tunnel.sock
|
||||
export RUST_LOG=info
|
||||
|
||||
@@ -25,7 +25,7 @@ sudo cp "rust/target/debug/$BINARY_NAME" "/usr/bin/$BINARY_NAME"
|
||||
|
||||
# Set up the systemd service
|
||||
sudo cp "rust/gui-client/src-tauri/deb_files/$SERVICE_NAME.service" /usr/lib/systemd/system/
|
||||
sudo cp "scripts/tests/systemd/env" "/etc/default/firezone-client-ipc"
|
||||
sudo cp "scripts/tests/systemd/env" "/etc/default/firezone-client-tunnel"
|
||||
|
||||
# The firezone group must exist before the daemon starts
|
||||
sudo groupadd "$FZ_GROUP"
|
||||
|
||||
@@ -15,7 +15,7 @@ by advanced users and admins.
|
||||
| Component | Log directory |
|
||||
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| macOS Client | `~/Library/Group Containers/47R2M6779T.dev.firezone.firezone/Library/Caches/logs` for the GUI process, and `/private/var/root/Library/Group Containers/47R2M6779T.dev.firezone.firezone/Library/Caches/logs` for the tunnel process |
|
||||
| Windows GUI Client | `%LOCALAPPDATA%\dev.firezone.client\data\logs` for the GUI process, and `%PROGRAMDATA%\dev.firezone.client\data\logs` for the IPC service |
|
||||
| Windows GUI Client | `%LOCALAPPDATA%\dev.firezone.client\data\logs` for the GUI process, and `%PROGRAMDATA%\dev.firezone.client\data\logs` for the Tunnel service |
|
||||
| Linux GUI Client | `$HOME/.cache/dev.firezone.client/data/logs/` for the GUI process, and `/var/log/dev.firezone.client/` for the tunnel process |
|
||||
| Android/ChromeOS Client | `/data/data/dev.firezone.android/caches/logs` |
|
||||
| iOS Client | N/A |
|
||||
|
||||
@@ -65,7 +65,7 @@ already work properly.
|
||||
from being auto-removed if Firezone is removed)
|
||||
3. `sudo dnf install ./firezone-client-gui-*.rpm`
|
||||
4. `sudo usermod -aG firezone-client $USER`
|
||||
5. `sudo systemctl enable firezone-client-ipc.service` (See
|
||||
5. `sudo systemctl enable firezone-client-tunnel.service` (See
|
||||
https://www.freedesktop.org/software/systemd/man/latest/systemd.preset.html,
|
||||
"It is not recommended to ship preset files within the respective software
|
||||
packages implementing the units". The Fedora family of distros also seem to
|
||||
@@ -153,12 +153,12 @@ To export or clear your logs:
|
||||
1. Click `Diagnostic Logs`.
|
||||
1. Click `Export Logs` or `Clear Log Directory`.
|
||||
|
||||
The IPC service (`firezone-client-ipc.service`) also logs to stdout which is
|
||||
captured by systemd and sent to journald. To view the logs of the IPC service,
|
||||
The Tunnel service (`firezone-client-tunnel.service`) also logs to stdout which is
|
||||
captured by systemd and sent to journald. To view the logs of the Tunnel service,
|
||||
use:
|
||||
|
||||
```bash
|
||||
journalctl --pager-end --follow --unit firezone-client-ipc.service
|
||||
journalctl --pager-end --follow --unit firezone-client-tunnel.service
|
||||
```
|
||||
|
||||
The GUI client logs to journald directly as well with the syslog identifier
|
||||
@@ -242,15 +242,15 @@ If the network interface stays up and DNS does not revert, you can try
|
||||
restarting the tunnel service. Quit the Firezone GUI, then run:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart firezone-client-ipc
|
||||
sudo systemctl restart firezone-client-tunnel
|
||||
```
|
||||
|
||||
### Viewing logs
|
||||
|
||||
The Firezone Client is split into 2 main processes: An IPC service which runs
|
||||
The Firezone Client is split into 2 main processes: A Tunnel service which runs
|
||||
the tunnel, and a GUI which allows the user to control Firezone.
|
||||
|
||||
- IPC service logs are stored at `/var/log/dev.firezone.client/`
|
||||
- Tunnel service logs are stored at `/var/log/dev.firezone.client/`
|
||||
- GUI logs are stored at `$HOME/.cache/dev.firezone.client/data/logs/`, where
|
||||
`$HOME` is, e.g. `/home/username/`
|
||||
|
||||
|
||||
@@ -127,13 +127,13 @@ To fix, perform these steps:
|
||||
`Settings -> Network and Internet -> Additional network settings -> Network Reset -> Reset now`.
|
||||
3. Reinstall Firezone and any other software you previously uninstalled.
|
||||
|
||||
### Check if Firezone Client IPC service is running
|
||||
### Check if Firezone Client Tunnel service is running
|
||||
|
||||
In the Start Menu, search for "Windows Powershell". Open it and run this
|
||||
command:
|
||||
|
||||
```pwsh
|
||||
Get-Service -Name FirezoneClientIpcService
|
||||
Get-Service -Name FirezoneClientTunnelService
|
||||
```
|
||||
|
||||
Good output
|
||||
@@ -202,10 +202,10 @@ Get-DnsClientNrptRule | where Comment -eq firezone-fd0020211111 | foreach { Remo
|
||||
|
||||
### Viewing logs
|
||||
|
||||
The Firezone Client is split into 2 main processes: An IPC service which runs
|
||||
The Firezone Client is split into 2 main processes: A Tunnel service which runs
|
||||
the tunnel, and a GUI which allows the user to control Firezone.
|
||||
|
||||
- IPC service logs are stored at `%PROGRAMDATA%\dev.firezone.client\data\logs\`,
|
||||
- Tunnel service logs are stored at `%PROGRAMDATA%\dev.firezone.client\data\logs\`,
|
||||
where `%PROGRAMDATA%` is almost always `C:\ProgramData`
|
||||
- GUI logs are stored at `%LOCALAPPDATA%\dev.firezone.client\data\logs`, where
|
||||
`%LOCALAPPDATA%` is, e.g. `C:\Users\username\AppData\Local`
|
||||
|
||||
@@ -17,6 +17,18 @@ export default function GUI({ os }: { os: OS }) {
|
||||
Launching Firezone while it is already running while now re-activate
|
||||
the "Welcome" screen, allowing the user to sign in and out.
|
||||
</ChangeItem>
|
||||
{os === OS.Windows && (
|
||||
<ChangeItem pull="9154">
|
||||
Renames the background service from `FirezoneClientIpcService`
|
||||
to `FirezoneClientTunnelService`.
|
||||
</ChangeItem>
|
||||
)}
|
||||
{os === OS.Linux && (
|
||||
<ChangeItem pull="9154">
|
||||
Renames the systemd service from `firezone-client-ipc.service`
|
||||
to `firezone-client-tunnel.service`.
|
||||
</ChangeItem>
|
||||
)}
|
||||
</Unreleased>
|
||||
<Entry version="1.4.13" date={new Date("2025-05-14")}>
|
||||
<ChangeItem pull="9014">
|
||||
|
||||
Reference in New Issue
Block a user