runsentry-agent 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. runsentry_agent-1.0.0/MANIFEST.in +5 -0
  2. runsentry_agent-1.0.0/PKG-INFO +262 -0
  3. runsentry_agent-1.0.0/README.md +237 -0
  4. runsentry_agent-1.0.0/pyproject.toml +50 -0
  5. runsentry_agent-1.0.0/runsentry/__init__.py +4 -0
  6. runsentry_agent-1.0.0/runsentry/__main__.py +8 -0
  7. runsentry_agent-1.0.0/runsentry/auth.py +140 -0
  8. runsentry_agent-1.0.0/runsentry/cli.py +105 -0
  9. runsentry_agent-1.0.0/runsentry/config.py +86 -0
  10. runsentry_agent-1.0.0/runsentry/daemon.py +223 -0
  11. runsentry_agent-1.0.0/runsentry/discovery/__init__.py +6 -0
  12. runsentry_agent-1.0.0/runsentry/discovery/cron.py +109 -0
  13. runsentry_agent-1.0.0/runsentry/discovery/k8s.py +74 -0
  14. runsentry_agent-1.0.0/runsentry/exec.py +123 -0
  15. runsentry_agent-1.0.0/runsentry/storage/__init__.py +7 -0
  16. runsentry_agent-1.0.0/runsentry/storage/buffer.py +82 -0
  17. runsentry_agent-1.0.0/runsentry/storage/inventory.py +124 -0
  18. runsentry_agent-1.0.0/runsentry/transport/__init__.py +6 -0
  19. runsentry_agent-1.0.0/runsentry/transport/client.py +135 -0
  20. runsentry_agent-1.0.0/runsentry-agent.service +16 -0
  21. runsentry_agent-1.0.0/runsentry_agent.egg-info/PKG-INFO +262 -0
  22. runsentry_agent-1.0.0/runsentry_agent.egg-info/SOURCES.txt +26 -0
  23. runsentry_agent-1.0.0/runsentry_agent.egg-info/dependency_links.txt +1 -0
  24. runsentry_agent-1.0.0/runsentry_agent.egg-info/entry_points.txt +2 -0
  25. runsentry_agent-1.0.0/runsentry_agent.egg-info/requires.txt +5 -0
  26. runsentry_agent-1.0.0/runsentry_agent.egg-info/top_level.txt +1 -0
  27. runsentry_agent-1.0.0/scripts/install.sh +153 -0
  28. runsentry_agent-1.0.0/setup.cfg +4 -0
@@ -0,0 +1,5 @@
1
+ include README.md
2
+ include scripts/install.sh
3
+ include runsentry-agent.service
4
+ recursive-include runsentry *.py
5
+
@@ -0,0 +1,262 @@
1
+ Metadata-Version: 2.4
2
+ Name: runsentry-agent
3
+ Version: 1.0.0
4
+ Summary: RunSentry Agent - Monitor and track scheduled job executions
5
+ Author-email: RunSentry <support@runsentry.io>
6
+ License: MIT
7
+ Project-URL: Homepage, https://runsentry.io
8
+ Project-URL: Documentation, https://docs.runsentry.io
9
+ Project-URL: Repository, https://github.com/runsentry/agent
10
+ Keywords: monitoring,cron,scheduled-jobs,observability
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: System Administrators
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: System :: Monitoring
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: requests>=2.31.0
22
+ Requires-Dist: pyyaml>=6.0
23
+ Provides-Extra: k8s
24
+ Requires-Dist: kubernetes>=28.0.0; extra == "k8s"
25
+
26
+ # RunSentry Agent
27
+
28
+ The RunSentry agent monitors and tracks scheduled job executions on Linux systems. It discovers cron jobs and Kubernetes CronJobs, tracks their executions, and sends data to the RunSentry backend.
29
+
30
+ ## Features
31
+
32
+ - 🔍 **Automatic Discovery**: Discovers cron jobs and Kubernetes CronJobs
33
+ - 📊 **Execution Tracking**: Tracks job start, finish, duration, and exit codes
34
+ - 🔒 **Secure**: Outbound-only HTTPS communication, no inbound ports
35
+ - 💾 **Resilient**: Local event buffering for offline operation
36
+ - 🚀 **Easy Installation**: One-line installer script
37
+
38
+ ## Quick Start
39
+
40
+ ### Installation
41
+
42
+ **One-line installation with automatic registration:**
43
+
44
+ ```bash
45
+ RUNSENTRY_TOKEN=your_token_here curl -fsSL https://get.runsentry.io/install.sh | bash
46
+ ```
47
+
48
+ The installer will:
49
+ 1. Validate Linux OS and Python 3.10+
50
+ 2. Create isolated virtual environment at `/opt/runsentry/venv`
51
+ 3. Install the RunSentry agent package
52
+ 4. Automatically register agent with backend (if `RUNSENTRY_TOKEN` is provided)
53
+ 5. Install and enable systemd service
54
+ 6. Start the service automatically if registration succeeds
55
+
56
+ **Installation without token (for later registration):**
57
+
58
+ ```bash
59
+ curl -fsSL https://get.runsentry.io/install.sh | bash
60
+
61
+ # Register manually later
62
+ RUNSENTRY_TOKEN=xxx /opt/runsentry/venv/bin/runsentry register --backend-url https://api.runsentry.io
63
+ systemctl start runsentry-agent
64
+ ```
65
+
66
+ **With custom backend URL:**
67
+
68
+ ```bash
69
+ RUNSENTRY_TOKEN=xxx RUNSENTRY_BACKEND_URL=https://api.example.com curl -fsSL https://get.runsentry.io/install.sh | bash
70
+ ```
71
+
72
+ ## Usage
73
+
74
+ ### Daemon Mode
75
+
76
+ The agent runs as a systemd service automatically after installation:
77
+
78
+ ```bash
79
+ # Check status
80
+ systemctl status runsentry-agent
81
+
82
+ # View logs
83
+ journalctl -u runsentry-agent -f
84
+
85
+ # Restart
86
+ systemctl restart runsentry-agent
87
+ ```
88
+
89
+ The daemon will:
90
+ - Discover jobs on startup and periodically (every hour)
91
+ - Flush buffered events to the backend (every minute)
92
+ - Run continuously until stopped
93
+
94
+ ### Execution Wrapper
95
+
96
+ Wrap your cron jobs to track executions:
97
+
98
+ ```bash
99
+ # Instead of:
100
+ 0 * * * * /path/to/script.sh
101
+
102
+ # Use:
103
+ 0 * * * * /opt/runsentry/venv/bin/runsentry exec /path/to/script.sh
104
+ ```
105
+
106
+ The wrapper will:
107
+ - Send execution start event
108
+ - Execute your command
109
+ - Capture exit code and duration
110
+ - Send execution finish event
111
+ - Works even if backend is temporarily unavailable (events are buffered)
112
+
113
+ ### CLI Commands
114
+
115
+ The agent exposes three commands:
116
+
117
+ - **`runsentry daemon`** - Run agent daemon (used by systemd service)
118
+ - **`runsentry exec <command>`** - Execute and track a job execution
119
+ - **`runsentry register`** - Register agent with backend (internal, used by install.sh)
120
+
121
+ **Note:** The `register` command is internal and used automatically by `install.sh`. Manual registration can be done if needed:
122
+ ```bash
123
+ /opt/runsentry/venv/bin/runsentry register --token xxx --backend-url https://api.runsentry.io
124
+ ```
125
+
126
+ ## Configuration
127
+
128
+ Configuration is stored at `/etc/runsentry/config.yaml`:
129
+
130
+ ```yaml
131
+ agent_id: agt_123
132
+ backend_url: https://api.runsentry.io
133
+ token: <signed-jwt>
134
+ agent_name: prod-vm-1
135
+ ```
136
+
137
+ ## Discovery
138
+
139
+ The agent automatically discovers:
140
+
141
+ - **Linux Cron**:
142
+ - User crontab (`crontab -l`)
143
+ - System crontab (`/etc/crontab`)
144
+ - Cron.d directory (`/etc/cron.d/*`)
145
+
146
+ - **Kubernetes CronJobs**:
147
+ - Requires `kubernetes` Python package
148
+ - Uses in-cluster config or kubeconfig
149
+ - Discovers all namespaces
150
+
151
+ ## Systemd Service
152
+
153
+ The agent runs as a systemd service:
154
+
155
+ ```bash
156
+ # Check status
157
+ systemctl status runsentry-agent
158
+
159
+ # View logs
160
+ journalctl -u runsentry-agent -f
161
+
162
+ # Restart
163
+ systemctl restart runsentry-agent
164
+
165
+ # Stop
166
+ systemctl stop runsentry-agent
167
+ ```
168
+
169
+ ## Upgrading
170
+
171
+ Upgrade the agent package manually:
172
+
173
+ ```bash
174
+ source /opt/runsentry/venv/bin/activate
175
+ pip install --upgrade runsentry-agent
176
+ systemctl restart runsentry-agent
177
+ ```
178
+
179
+ Configuration is preserved during upgrades.
180
+
181
+ ## Development
182
+
183
+ ### Local Development Setup
184
+
185
+ ```bash
186
+ # Clone repository
187
+ git clone https://github.com/runsentry/agent.git
188
+ cd agent
189
+
190
+ # Create virtual environment
191
+ python3 -m venv venv
192
+ source venv/bin/activate
193
+
194
+ # Install in development mode
195
+ pip install -e .
196
+
197
+ # Install with Kubernetes support
198
+ pip install -e ".[k8s]"
199
+ ```
200
+
201
+ ### Running Tests
202
+
203
+ ```bash
204
+ pytest
205
+ ```
206
+
207
+ ## Architecture
208
+
209
+ The agent operates in two modes:
210
+
211
+ 1. **Daemon Mode**: Continuous background process for discovery and sync
212
+ 2. **Exec Mode**: Wrapper for individual job executions
213
+
214
+ All communication is outbound-only HTTPS to the RunSentry backend.
215
+
216
+ ## Security
217
+
218
+ - ✅ Outbound-only HTTPS
219
+ - ✅ Token-based authentication
220
+ - ✅ Signed agent JWT
221
+ - ✅ Read-only discovery permissions
222
+ - ✅ No inbound ports
223
+ - ✅ Secure configuration file (600 permissions)
224
+
225
+ ## Requirements
226
+
227
+ - Python 3.10+
228
+ - Linux (Ubuntu, Debian, RHEL, etc.)
229
+ - Network access to RunSentry backend
230
+ - Root or sudo access for installation
231
+
232
+ ## Troubleshooting
233
+
234
+ ### Agent not discovering jobs
235
+
236
+ - Check that cron jobs exist: `crontab -l`
237
+ - Verify agent has read permissions to `/etc/crontab` and `/etc/cron.d/`
238
+ - Check daemon logs: `journalctl -u runsentry-agent`
239
+
240
+ ### Events not reaching backend
241
+
242
+ - Check network connectivity to backend URL
243
+ - Verify agent token is valid
244
+ - Check buffered events: `/var/lib/runsentry/buffer/events.jsonl`
245
+ - Review logs for errors
246
+
247
+ ### Service won't start
248
+
249
+ - Check Python version: `python3 --version`
250
+ - Verify virtual environment exists: `/opt/runsentry/venv`
251
+ - Check systemd logs: `journalctl -u runsentry-agent`
252
+
253
+ ## License
254
+
255
+ MIT License
256
+
257
+ ## Support
258
+
259
+ For issues and questions:
260
+ - Documentation: https://docs.runsentry.io
261
+ - Support: support@runsentry.io
262
+
@@ -0,0 +1,237 @@
1
+ # RunSentry Agent
2
+
3
+ The RunSentry agent monitors and tracks scheduled job executions on Linux systems. It discovers cron jobs and Kubernetes CronJobs, tracks their executions, and sends data to the RunSentry backend.
4
+
5
+ ## Features
6
+
7
+ - 🔍 **Automatic Discovery**: Discovers cron jobs and Kubernetes CronJobs
8
+ - 📊 **Execution Tracking**: Tracks job start, finish, duration, and exit codes
9
+ - 🔒 **Secure**: Outbound-only HTTPS communication, no inbound ports
10
+ - 💾 **Resilient**: Local event buffering for offline operation
11
+ - 🚀 **Easy Installation**: One-line installer script
12
+
13
+ ## Quick Start
14
+
15
+ ### Installation
16
+
17
+ **One-line installation with automatic registration:**
18
+
19
+ ```bash
20
+ RUNSENTRY_TOKEN=your_token_here curl -fsSL https://get.runsentry.io/install.sh | bash
21
+ ```
22
+
23
+ The installer will:
24
+ 1. Validate Linux OS and Python 3.10+
25
+ 2. Create isolated virtual environment at `/opt/runsentry/venv`
26
+ 3. Install the RunSentry agent package
27
+ 4. Automatically register agent with backend (if `RUNSENTRY_TOKEN` is provided)
28
+ 5. Install and enable systemd service
29
+ 6. Start the service automatically if registration succeeds
30
+
31
+ **Installation without token (for later registration):**
32
+
33
+ ```bash
34
+ curl -fsSL https://get.runsentry.io/install.sh | bash
35
+
36
+ # Register manually later
37
+ RUNSENTRY_TOKEN=xxx /opt/runsentry/venv/bin/runsentry register --backend-url https://api.runsentry.io
38
+ systemctl start runsentry-agent
39
+ ```
40
+
41
+ **With custom backend URL:**
42
+
43
+ ```bash
44
+ RUNSENTRY_TOKEN=xxx RUNSENTRY_BACKEND_URL=https://api.example.com curl -fsSL https://get.runsentry.io/install.sh | bash
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ### Daemon Mode
50
+
51
+ The agent runs as a systemd service automatically after installation:
52
+
53
+ ```bash
54
+ # Check status
55
+ systemctl status runsentry-agent
56
+
57
+ # View logs
58
+ journalctl -u runsentry-agent -f
59
+
60
+ # Restart
61
+ systemctl restart runsentry-agent
62
+ ```
63
+
64
+ The daemon will:
65
+ - Discover jobs on startup and periodically (every hour)
66
+ - Flush buffered events to the backend (every minute)
67
+ - Run continuously until stopped
68
+
69
+ ### Execution Wrapper
70
+
71
+ Wrap your cron jobs to track executions:
72
+
73
+ ```bash
74
+ # Instead of:
75
+ 0 * * * * /path/to/script.sh
76
+
77
+ # Use:
78
+ 0 * * * * /opt/runsentry/venv/bin/runsentry exec /path/to/script.sh
79
+ ```
80
+
81
+ The wrapper will:
82
+ - Send execution start event
83
+ - Execute your command
84
+ - Capture exit code and duration
85
+ - Send execution finish event
86
+ - Works even if backend is temporarily unavailable (events are buffered)
87
+
88
+ ### CLI Commands
89
+
90
+ The agent exposes three commands:
91
+
92
+ - **`runsentry daemon`** - Run agent daemon (used by systemd service)
93
+ - **`runsentry exec <command>`** - Execute and track a job execution
94
+ - **`runsentry register`** - Register agent with backend (internal, used by install.sh)
95
+
96
+ **Note:** The `register` command is internal and used automatically by `install.sh`. Manual registration can be done if needed:
97
+ ```bash
98
+ /opt/runsentry/venv/bin/runsentry register --token xxx --backend-url https://api.runsentry.io
99
+ ```
100
+
101
+ ## Configuration
102
+
103
+ Configuration is stored at `/etc/runsentry/config.yaml`:
104
+
105
+ ```yaml
106
+ agent_id: agt_123
107
+ backend_url: https://api.runsentry.io
108
+ token: <signed-jwt>
109
+ agent_name: prod-vm-1
110
+ ```
111
+
112
+ ## Discovery
113
+
114
+ The agent automatically discovers:
115
+
116
+ - **Linux Cron**:
117
+ - User crontab (`crontab -l`)
118
+ - System crontab (`/etc/crontab`)
119
+ - Cron.d directory (`/etc/cron.d/*`)
120
+
121
+ - **Kubernetes CronJobs**:
122
+ - Requires `kubernetes` Python package
123
+ - Uses in-cluster config or kubeconfig
124
+ - Discovers all namespaces
125
+
126
+ ## Systemd Service
127
+
128
+ The agent runs as a systemd service:
129
+
130
+ ```bash
131
+ # Check status
132
+ systemctl status runsentry-agent
133
+
134
+ # View logs
135
+ journalctl -u runsentry-agent -f
136
+
137
+ # Restart
138
+ systemctl restart runsentry-agent
139
+
140
+ # Stop
141
+ systemctl stop runsentry-agent
142
+ ```
143
+
144
+ ## Upgrading
145
+
146
+ Upgrade the agent package manually:
147
+
148
+ ```bash
149
+ source /opt/runsentry/venv/bin/activate
150
+ pip install --upgrade runsentry-agent
151
+ systemctl restart runsentry-agent
152
+ ```
153
+
154
+ Configuration is preserved during upgrades.
155
+
156
+ ## Development
157
+
158
+ ### Local Development Setup
159
+
160
+ ```bash
161
+ # Clone repository
162
+ git clone https://github.com/runsentry/agent.git
163
+ cd agent
164
+
165
+ # Create virtual environment
166
+ python3 -m venv venv
167
+ source venv/bin/activate
168
+
169
+ # Install in development mode
170
+ pip install -e .
171
+
172
+ # Install with Kubernetes support
173
+ pip install -e ".[k8s]"
174
+ ```
175
+
176
+ ### Running Tests
177
+
178
+ ```bash
179
+ pytest
180
+ ```
181
+
182
+ ## Architecture
183
+
184
+ The agent operates in two modes:
185
+
186
+ 1. **Daemon Mode**: Continuous background process for discovery and sync
187
+ 2. **Exec Mode**: Wrapper for individual job executions
188
+
189
+ All communication is outbound-only HTTPS to the RunSentry backend.
190
+
191
+ ## Security
192
+
193
+ - ✅ Outbound-only HTTPS
194
+ - ✅ Token-based authentication
195
+ - ✅ Signed agent JWT
196
+ - ✅ Read-only discovery permissions
197
+ - ✅ No inbound ports
198
+ - ✅ Secure configuration file (600 permissions)
199
+
200
+ ## Requirements
201
+
202
+ - Python 3.10+
203
+ - Linux (Ubuntu, Debian, RHEL, etc.)
204
+ - Network access to RunSentry backend
205
+ - Root or sudo access for installation
206
+
207
+ ## Troubleshooting
208
+
209
+ ### Agent not discovering jobs
210
+
211
+ - Check that cron jobs exist: `crontab -l`
212
+ - Verify agent has read permissions to `/etc/crontab` and `/etc/cron.d/`
213
+ - Check daemon logs: `journalctl -u runsentry-agent`
214
+
215
+ ### Events not reaching backend
216
+
217
+ - Check network connectivity to backend URL
218
+ - Verify agent token is valid
219
+ - Check buffered events: `/var/lib/runsentry/buffer/events.jsonl`
220
+ - Review logs for errors
221
+
222
+ ### Service won't start
223
+
224
+ - Check Python version: `python3 --version`
225
+ - Verify virtual environment exists: `/opt/runsentry/venv`
226
+ - Check systemd logs: `journalctl -u runsentry-agent`
227
+
228
+ ## License
229
+
230
+ MIT License
231
+
232
+ ## Support
233
+
234
+ For issues and questions:
235
+ - Documentation: https://docs.runsentry.io
236
+ - Support: support@runsentry.io
237
+
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "runsentry-agent"
7
+ version = "1.0.0"
8
+ description = "RunSentry Agent - Monitor and track scheduled job executions"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "RunSentry", email = "support@runsentry.io"}
14
+ ]
15
+ keywords = ["monitoring", "cron", "scheduled-jobs", "observability"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: System Administrators",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: System :: Monitoring",
25
+ ]
26
+
27
+ dependencies = [
28
+ "requests>=2.31.0",
29
+ "pyyaml>=6.0",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ k8s = [
34
+ "kubernetes>=28.0.0",
35
+ ]
36
+
37
+ [project.scripts]
38
+ runsentry = "runsentry.cli:main"
39
+
40
+ [project.urls]
41
+ Homepage = "https://runsentry.io"
42
+ Documentation = "https://docs.runsentry.io"
43
+ Repository = "https://github.com/runsentry/agent"
44
+
45
+ [tool.setuptools]
46
+ packages = ["runsentry", "runsentry.discovery", "runsentry.storage", "runsentry.transport"]
47
+
48
+ [tool.setuptools.package-data]
49
+ runsentry = ["*.yaml", "*.yml"]
50
+
@@ -0,0 +1,4 @@
1
+ """RunSentry Agent - Monitor and track scheduled job executions."""
2
+
3
+ __version__ = "1.0.0"
4
+
@@ -0,0 +1,8 @@
1
+ """CLI entrypoint for RunSentry agent."""
2
+
3
+ import sys
4
+ from runsentry.cli import main
5
+
6
+ if __name__ == "__main__":
7
+ sys.exit(main())
8
+
@@ -0,0 +1,140 @@
1
+ """Authentication and agent registration.
2
+
3
+ Internal module used by install.sh for agent registration.
4
+ Not intended for direct user use.
5
+ """
6
+
7
+ import logging
8
+ import sys
9
+ import os
10
+ import time
11
+ import platform
12
+ import socket
13
+ import requests
14
+ from typing import Optional
15
+ from runsentry.config import get_config, CONFIG_PATH
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def register_agent(token: str, backend_url: str, agent_name: Optional[str] = None, retries: int = 3, retry_delay: int = 5) -> bool:
21
+ """
22
+ Register agent with RunSentry backend.
23
+
24
+ Internal function used by install.sh. Handles registration with retries
25
+ and saves configuration.
26
+
27
+ Args:
28
+ token: Registration token (required)
29
+ backend_url: Backend URL (required)
30
+ agent_name: Agent name (optional, defaults to hostname)
31
+ retries: Number of registration retry attempts (default: 3)
32
+ retry_delay: Delay between retries in seconds (default: 5)
33
+
34
+ Returns:
35
+ True if registration successful, False otherwise
36
+ """
37
+ if not token:
38
+ logger.error("Registration token is required")
39
+ return False
40
+
41
+ if not backend_url:
42
+ logger.error("Backend URL is required")
43
+ return False
44
+
45
+ config = get_config()
46
+
47
+ # Check if already configured (idempotency)
48
+ if config.is_configured():
49
+ logger.info(f"Agent is already configured (ID: {config.agent_id})")
50
+ return True
51
+
52
+ # Detect agent name if not provided
53
+ if not agent_name:
54
+ agent_name = os.environ.get("RUNSENTRY_AGENT_NAME") or socket.gethostname()
55
+
56
+ # Detect host information
57
+ hostname = socket.gethostname()
58
+ os_name = platform.system().lower()
59
+ arch = platform.machine()
60
+
61
+ # Detect agent type
62
+ agent_type = "linux-cron"
63
+ if os.path.exists("/var/run/secrets/kubernetes.io"):
64
+ agent_type = "kubernetes"
65
+
66
+ payload = {
67
+ "agentName": agent_name,
68
+ "agentType": agent_type,
69
+ "version": "1.0.0",
70
+ "host": {
71
+ "hostname": hostname,
72
+ "os": os_name,
73
+ "arch": arch,
74
+ },
75
+ }
76
+
77
+ # Retry logic for registration
78
+ logger.info(f"Registering agent with backend: {backend_url}")
79
+ logger.info(f"Agent name: {agent_name}")
80
+
81
+ for attempt in range(1, retries + 1):
82
+ try:
83
+ response = requests.post(
84
+ f"{backend_url}/api/v1/agents/register",
85
+ json=payload,
86
+ headers={
87
+ "Content-Type": "application/json",
88
+ "X-Registration-Token": token,
89
+ },
90
+ timeout=30,
91
+ )
92
+ response.raise_for_status()
93
+
94
+ data = response.json()
95
+ agent_id = data.get("agentId")
96
+ agent_token = data.get("token") # Non-expiring token for all API calls
97
+ workspace_id = data.get("workspaceId")
98
+ backend_url_from_response = data.get("backendUrl", backend_url)
99
+
100
+ if not agent_id or not agent_token:
101
+ raise ValueError("Invalid response from backend: missing agentId or token")
102
+
103
+ # Save configuration
104
+ config.agent_id = agent_id
105
+ config.token = agent_token # This token never expires, use for all API calls
106
+ config.backend_url = backend_url_from_response # Use backend URL from response
107
+ config.agent_name = agent_name
108
+ if workspace_id:
109
+ config.workspace_id = workspace_id
110
+ config.save()
111
+
112
+ logger.info(f"Successfully registered agent: {agent_name} ({agent_id})")
113
+ logger.info(f"Configuration saved to {CONFIG_PATH}")
114
+
115
+ return True
116
+
117
+ except requests.exceptions.RequestException as e:
118
+ if attempt < retries:
119
+ logger.warning(f"Registration attempt {attempt}/{retries} failed: {e}")
120
+ logger.info(f"Retrying in {retry_delay} seconds...")
121
+ time.sleep(retry_delay)
122
+ else:
123
+ logger.error(f"Failed to register agent after {retries} attempts")
124
+ if hasattr(e, "response") and e.response is not None:
125
+ try:
126
+ error_data = e.response.json()
127
+ logger.error(f"Backend error: {error_data}")
128
+ except:
129
+ logger.error(f"Response: {e.response.text}")
130
+ else:
131
+ logger.error(f"Error details: {e}")
132
+ continue
133
+ except Exception as e:
134
+ logger.error(f"Unexpected error during registration: {e}", exc_info=True)
135
+ if attempt < retries:
136
+ time.sleep(retry_delay)
137
+ continue
138
+
139
+ return False
140
+