Skip to content

feat: add P2Poolv2 systemd service controls - #34

Open
R27-pixel wants to merge 4 commits into
p2poolv2:mainfrom
R27-pixel:p2poolv2_service
Open

R27-pixel wants to merge 4 commits into
p2poolv2:mainfrom
R27-pixel:p2poolv2_service

Conversation

@R27-pixel

@R27-pixel R27-pixel commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds user-level systemd service controls for P2Poolv2 in PDM.

P2Poolv2 systemd integration

  • Added a user-level templated systemd service through p2poolv2@.service.

  • PDM derives the service instance from managed config filenames:

    <XDG_CONFIG_HOME>/p2poolv2/config-signet.toml
    → signet
    → p2poolv2@signet
    
  • PDM controls the service through systemctl --user:

    • Start: p2poolv2@<instance>
    • Stop: p2poolv2@<instance>
    • Restart: p2poolv2@<instance>
    • Status: systemctl --user is-active p2poolv2@<instance>
  • The systemd service launches the matching P2Poolv2 config file using %i.

  • PDM edits and monitors the same config file used by the systemd service.

  • Closing PDM does not stop P2Poolv2; the user service continues running.

  • Reopening PDM restores the selected config and reconnects to the existing service.

Config handling

Managed service configs must be directly under the user's P2Poolv2 config directory and follow:

config-<instance>.toml

Instance names are restricted to letters, digits, _, and -.

Arbitrary config paths remain supported for loading, editing, saving, and API monitoring, but systemd lifecycle controls are unavailable for those configs.

Error handling

Start, Stop, and Restart failures are caught by PDM and displayed in the System tab instead of propagating as fatal errors and terminating the application.

Setup

Install the user service unit at:

~/.config/systemd/user/p2poolv2@.service

Install the P2Poolv2 binary at:

~/.local/bin/p2poolv2

After installing or changing the unit, reload the user systemd manager:

systemctl --user daemon-reload

@codecov

codecov Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.03654% with 66 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/main.rs 62.22% 34 Missing ⚠️
src/app.rs 91.70% 19 Missing ⚠️
src/p2poolv2_service.rs 91.71% 13 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Critical and moderate review issues remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity · 5 Medium severity

Open (7)
What changed in this PR

Adds user-level systemd controls for P2Poolv2, config-derived service instances, and monitoring integration.

Changes:

  • Adds templated systemd lifecycle controls.
  • Uses P2Poolv2 configuration for API, RPC, and WebSocket clients.
  • Updates UI, settings, fixtures, and snapshots.
  • Removes legacy Bitcoin configuration, Lightning, and Shares Market workflows.
File Summary / final review note
tests/​snapshots/​ui_snapshots__home_screen_render.snap Updates home snapshot.
tests/​snapshots/​ui_snapshots__config_screen_render.snap Updates config snapshot.
tests/​fixtures/​p2pool.toml Adds P2Poolv2 fixture.
systemd/​user/​p2poolv2@.service Adds service unit. Moderate (1 vote): relative log/stat directories are not created.
src/​ui.rs Updates screen rendering and tests.
src/​snapshots/​pdm__ui__tests__shares_market_screen_render.snap Removes obsolete snapshot.
src/​snapshots/​pdm__ui__tests__settings_screen_render.snap Updates settings snapshot.
src/​snapshots/​pdm__ui__tests__p2pool_status_screen_render.snap Updates P2Pool status snapshot.
src/​snapshots/​pdm__ui__tests__p2pool_screen_render.snap Updates P2Pool snapshot.
src/​snapshots/​pdm__ui__tests__p2pool_config_screen_render.snap Updates P2Pool config snapshot.
src/​snapshots/​pdm__ui__tests__ln_status_screen_render.snap Removes obsolete snapshot.
src/​snapshots/​pdm__ui__tests__ln_config_screen_render.snap Removes obsolete snapshot.
src/​snapshots/​pdm__ui__tests__home_screen_render.snap Updates home snapshot.
src/​snapshots/​pdm__ui__tests__bitcoin_status_tab_system_render.snap Updates Bitcoin status snapshot.
src/​snapshots/​pdm__ui__tests__bitcoin_status_tab_peers_render.snap Updates Bitcoin peers snapshot.
src/​snapshots/​pdm__ui__tests__bitcoin_status_tab_logs_render.snap Updates Bitcoin logs snapshot.
src/​snapshots/​pdm__ui__tests__bitcoin_status_screen_render.snap Updates Bitcoin status snapshot.
src/​snapshots/​pdm__ui__tests__bitcoin_screen_render.snap Updates Bitcoin snapshot.
src/​snapshots/​pdm__ui__tests__bitcoin_config_screen_render.snap Updates Bitcoin config snapshot.
src/​snapshots/​pdm__tests__menu_toggled.snap Updates menu snapshot.
src/​snapshots/​pdm__tests__home_screen.snap Updates home snapshot.
src/​settings.rs Removes legacy settings paths.
src/​p2poolv2_service.rs Implements service controls. Critical (1 vote): systemd-specific tests are not portable to Windows.
src/​p2poolv2_config.rs Updates configuration documentation.
src/​main.rs Adds service actions and config integration.
src/​lib.rs Updates exported modules.
src/​config.rs Removes obsolete API configuration.
src/​components/​status_bar.rs Updates navigation and status hints.
src/​components/​shares_market_view.rs Removes legacy marketplace view.
src/​components/​settings_view.rs Reduces settings fields.
src/​components/​p2pool_websocket.rs Uses configured WebSocket settings. Moderate (2 votes): IPv6 hosts produce invalid URLs without brackets.
src/​components/​p2pool_status_view.rs Adds service status and controls. Moderate (4 votes): synchronous status checks can block rendering. Moderate (2 votes): query failures are misleadingly shown as stopped.
src/​components/​p2pool_client.rs Uses P2Pool API settings. Moderate (2 votes): IPv6 hosts produce invalid HTTP URLs without brackets.
src/​components/​mod.rs Removes obsolete modules.
src/​components/​ln_status_view.rs Removes legacy Lightning status view.
src/​components/​ln_config_view.rs Removes legacy Lightning config view.
src/​components/​bitcoin_status_view.rs Updates Bitcoin monitoring dependencies.
src/​components/​bitcoin_config_view.rs Removes Bitcoin config editor.
src/​components/​bitcoin_client.rs Uses Bitcoin RPC settings from P2Pool configuration.
src/​app.rs Adds config/client lifecycle handling. Critical (4 votes): removes existing Bitcoin configuration workflow without an explicit deprecation. Moderate (2 votes): previous WebSocket tasks are not cancelled when replacing clients.
config/​config.toml Removes obsolete configuration.
config/​config.sample.toml Removes obsolete sample configuration.
Cargo.toml Removes obsolete dependency.
Cargo.lock Updates dependency lockfile.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/app.rs

/// Sidebar items labels
pub const SIDEBAR_ITEMS: &[(&str, CurrentScreen)] = &[
("Home", CurrentScreen::Home),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The readme needs to be update, will address this in a separate PR!.

Comment thread src/p2poolv2_service.rs
Comment on lines +104 to +105
#[cfg(test)]
mod tests {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The Unix-specific systemctl test helpers and tests are now gated with #[cfg(unix)], including the PermissionsExt import. The platform-independent tests remain available on other platforms.

Comment thread src/app.rs
Comment on lines +193 to +197
pub fn set_p2pool_config(&mut self, config: P2PoolConfig) {
self.p2pool_config = Some(config);
self.p2pool_service_error = None;
self.refresh_p2pool_clients_from_config();
self.clear_p2pool_status_data();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The live WebSocket task is now stored as a JoinHandle and aborted when the P2Pool configuration is cleared or refreshed, preventing the previous configuration's live stream from continuing in the background.

Comment thread src/components/p2pool_client.rs Outdated
Comment on lines +82 to +84
fn from_api_config(config: &P2PoolApiConfig) -> Self {
let client =
P2PoolClient::with_base_url(format!("http://{}:{}", config.hostname, config.port));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. IPv6 literals are now detected and bracketed when constructing the P2Pool API base URL, while IPv4 addresses and hostnames remain unchanged. Added a test covering an IPv6 API hostname.

Comment thread src/components/p2pool_status_view.rs Outdated
.as_deref()
.and_then(instance_from_config_path)
{
let running = P2PoolV2Service::is_running(&instance).unwrap_or(false);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The P2Pool service status query is now performed asynchronously using spawn_blocking and its result is cached through an mpsc channel. The TUI renderer now reads the cached result instead of invoking systemctl during rendering.

Comment thread src/components/p2pool_status_view.rs Outdated
.as_deref()
.and_then(instance_from_config_path)
{
let running = P2PoolV2Service::is_running(&instance).unwrap_or(false);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Service status now distinguishes between Running, Stopped, Unavailable when the status query fails, and Unknown while no result is available. Added tests covering all four states.

Comment thread src/components/p2pool_websocket.rs Outdated
Comment on lines +82 to +86
fn from_api_config(config: &P2PoolApiConfig) -> Self {
let client = P2PoolWebSocketClient::with_base_url(format!(
"http://{}:{}",
config.hostname, config.port
));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. IPv6 literals are now bracketed when constructing the WebSocket client's base URL, matching the API client's handling. Added a test verifying that ::1 produces ws://[::1]:/ws.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants