freenet-core icon indicating copy to clipboard operation
freenet-core copied to clipboard

Add a `freenet service enable/disable` subcommand for running Freenet as a background user-level service

Open sanity opened this issue 8 months ago • 0 comments

Summary:
We want to provide an easy way for users to run Freenet as a background service without requiring manual startup each time. The consensus is to add a freenet service enable and freenet service disable command (rather than “install/uninstall”). This subcommand will create user-level services—rather than system-wide ones—because Freenet doesn’t require privileged access. It’s also safer for alpha-grade software to be sandboxed under a non-root user by default.


Detailed Proposal

1. Command-Line Interface Changes

  • freenet service enable:
    • Sets up Freenet to run as a background, user-level service on startup.
    • Immediately starts Freenet in the background.
  • freenet service disable:
    • Disables and removes the user-level service.
    • Stops Freenet if it’s currently running.

(Optional) You might later add freenet service status or freenet service logs, but for now, let’s focus on enable/disable.

2. Cross-Platform Approach

2.1 Linux (User-Level systemd Units)

  1. Detect systemd (typical in most modern distributions):
    • Check if systemctl is available.
  2. Create a user-level systemd unit:
    • The file can be placed under ~/.config/systemd/user/freenet.service.
    • Sample unit file:
      [Unit]
      Description=Freenet User Service
      
      [Service]
      Type=simple
      ExecStart=/usr/bin/freenet
      Restart=on-failure
      
      [Install]
      WantedBy=default.target
      
  3. Enable the user service:
    systemctl --user daemon-reload
    systemctl --user enable freenet
    systemctl --user start freenet
    
  4. Disable/Remove:
    systemctl --user stop freenet
    systemctl --user disable freenet
    rm ~/.config/systemd/user/freenet.service
    systemctl --user daemon-reload
    
  5. Fallback (Non-systemd environments):
    • If there’s no systemd, optionally detect other init systems or provide a manual warning that auto-service mode is unavailable.

2.2 macOS (User-Level Launch Agents)

  1. Generate a Launch Agent plist:
    • Typically goes in ~/Library/LaunchAgents/org.freenet.service.plist.
    • Example:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
      "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
        <dict>
          <key>Label</key>
          <string>org.freenet.service</string>
          <key>ProgramArguments</key>
          <array>
            <string>/usr/local/bin/freenet</string>
          </array>
          <key>RunAtLoad</key>
          <true/>
          <key>KeepAlive</key>
          <true/>
        </dict>
      </plist>
      
  2. Enable the user Launch Agent:
    launchctl load ~/Library/LaunchAgents/org.freenet.service.plist
    launchctl start org.freenet.service
    
  3. Disable/Remove:
    launchctl stop org.freenet.service
    launchctl unload ~/Library/LaunchAgents/org.freenet.service.plist
    rm ~/Library/LaunchAgents/org.freenet.service.plist
    

2.3 Windows (User-Level Equivalent)

Windows doesn’t have an exact “user-level service” concept like Linux or macOS. However, we can mimic it in one of two ways:

  1. Windows Services
    • By default, sc create sets up a system-level service. This requires administrator privileges. Since we want user-level, this approach may be more complicated, involving special configurations (e.g., run as the current user’s credentials).
  2. Scheduled Task
    • An alternate method is creating a scheduled task that triggers on user logon to run Freenet in the background.
    • For example:
      schtasks /create /tn "FreenetUserService" /tr "C:\Path\To\freenet.exe" /sc onlogon
      
    • Disabling it:
      schtasks /delete /tn "FreenetUserService"
      
    • This is not a true “service” but still achieves “run Freenet automatically when this user logs in.”

Recommendation for Windows:

  • Since the request is specifically user-level, a scheduled task is likely the simplest approach without requiring admin privileges.
  • If a real service is preferred, you’ll need to prompt for admin rights and optionally configure the “Log on as” user.

3. Implementation Outline

  • freenet service enable:

    1. Detect OS (Linux/macOS/Windows).
    2. If Linux, detect systemd and place a systemd user unit in ~/.config/systemd/user/.
    3. If macOS, place a Launch Agent plist in ~/Library/LaunchAgents/.
    4. If Windows, create a scheduled task (assuming no admin privileges).
    5. Immediately start the service so Freenet is running in background.
  • freenet service disable:

    1. Detect OS.
    2. Reverse the above steps (stop and remove the service file or scheduled task).
    3. Confirm that Freenet is no longer running in background.

4. Error Handling & Reporting

  • If systemd (or another manager) is unavailable, print a warning that the service can’t be enabled automatically.
  • If a service file already exists and is enabled, warn or ask the user for confirmation before overriding.
  • If a service cannot be stopped or removed, display the relevant error message.

5. Future Enhancements

  • freenet service status for quick checks (running/stopped, logs, etc.).
  • freenet service logs might show tail of logs if supported.
  • Options for specifying a custom location of the Freenet binary or custom config paths.

Conclusion:
Implementing freenet service enable/disable for user-level services will let Freenet run automatically in the background across Linux, macOS, and Windows (with some OS-specific variations). This reduces friction for newcomers and offers a safer default than system-wide installation.

sanity avatar Mar 21 '25 17:03 sanity