Overview
Problem
Jenkins inbound (JNLP) agents on Windows typically require:
- A user to be logged in running
java -jar agent.jarin a terminal - A scheduled task workaround that is fragile and lacks proper service lifecycle management
- Manual restarts after reboots or crashes
Solution
JenkinsAsService wraps the Jenkins inbound agent connection inside a native Windows Service built with .NET 10. The service:
- Reads configuration from
appsettings.json - Validates all settings (Jenkins URL with explicit port, agent secret, Java path)
- Tests TCP connectivity to the Jenkins controller
- Downloads
agent.jarusing ETag-based conditional GET (skips on 304 Not Modified) - Launches the Java agent process with async output parsing and secret redaction
- Monitors the agent via an event-driven watchdog with exponential backoff auto-recovery
Key Benefits
- Auto-start on boot — runs under LocalSystem, no interactive login required
- Event-driven watchdog — detects agent death instantly via
process.Exited/TaskCompletionSource, auto-recovers with exponential backoff (10s→300s) - Smart jar caching — ETag-based conditional GET (
If-None-Match/ 304 Not Modified) skips the download when the jar is unchanged - Secret protection — DPAPI machine-scope encryption, Windows Credential Manager, system env var, or plaintext. CLI subcommand
update-secretwith--impersonatesupport - HTTP resilience — Polly-based retry, circuit breaker, and timeout via
Microsoft.Extensions.Http.Resilience - SEVERE crash diagnostics — counts
SEVERE:lines per agent run; logs the count on each exit - OpenTelemetry metrics —
jenkins_agent_restarts_total,jenkins_agent_severe_events_total, .NET runtime metrics. Opt-in viaTelemetry:Enabled: true - Dual logging — Serilog rolling file (
agent.logoragent.clef) plus Windows Event Log - Secret redaction — agent secrets scrubbed from all log output
- Single-file deploy — self-contained .exe with R2R, compression, and embedded PDB
- 59 unit tests — xUnit + NSubstitute + FluentAssertions, CI on every push
How It Works
flowchart TD
A[Windows Service Manager] -->|Calls ExecuteAsync| B[Validate Settings]
B --> C{Settings OK?}
C -->|No| D[Log Error & Stop]
C -->|Yes| E[Resolve Java Path]
E --> F[Test TCP Connectivity]
F -->|Fail| D
F -->|Pass| G["Download agent.jar (ETag cached)"]
G --> H[Start Java Process]
H --> I[Watchdog Loop]
I -->|process.Exited or 60s timer| J{Process exited?}
J -->|No — stable 60s| K[Reset retry counter]
K --> I
J -->|Yes| L["Log SEVERE count, Backoff, Re-download, Restart"]
L --> I