flux-config-shared 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,402 @@
1
+ """JSON-RPC 2.0 protocol definitions for daemon/client communication."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum, auto
6
+ from typing import Any
7
+
8
+ from pydantic import BaseModel, Field
9
+
10
+
11
+ class InstallState(Enum):
12
+ """Overall installation state of the system."""
13
+
14
+ NEW = auto() # First-time installation
15
+ RESUMING = auto() # Resuming incomplete installation
16
+ COMPLETE = auto() # All tasks finished
17
+ CANCELLED = auto() # Installation was cancelled by user
18
+ SCHEMA_MIGRATION = auto() # Schema was updated, some tasks done
19
+ RECONFIGURING_NOW = auto() # User chose to reconfigure now
20
+ RECONFIGURING_LATER = auto() # User chose to reconfigure later
21
+ UNKNOWN = auto() # Initial state before loading from DB
22
+
23
+
24
+ class MethodName(str, Enum):
25
+ """RPC method names (Client → Daemon)."""
26
+
27
+ # Subscriptions (topic-based event streaming)
28
+ SUBSCRIBE = "subscribe"
29
+ UNSUBSCRIBE = "unsubscribe"
30
+
31
+ # Configuration
32
+ CONFIG_GET_USER = "config.get_user"
33
+ CONFIG_SET_USER = "config.set_user"
34
+ CONFIG_GET_INSTALLER = "config.get_installer"
35
+ CONFIG_GET_APP = "config.get_app"
36
+ CONFIG_UPDATE_APP = "config.update_app"
37
+ CONFIG_VALIDATE_PUBKEY = "config.validate_pubkey"
38
+ CONFIG_WRITE_FLUXD_GENERIC = "config.write_fluxd_generic"
39
+ CONFIG_CREATE_FLUXD = "config.create_fluxd"
40
+ CONFIG_REMOVE = "config.remove"
41
+ CONFIG_GET_SHAPING_POLICY = "config.get_shaping_policy"
42
+
43
+ # State Management
44
+ STATE_POPULATE = "state.populate"
45
+ STATE_GET_RECONFIGURE = "state.get_reconfigure"
46
+ STATE_CREATE_MARKER = "state.create_marker"
47
+ STATE_REMOVE_MARKER = "state.remove_marker"
48
+ STATE_MARKER_EXISTS = "state.marker_exists"
49
+
50
+ # Service Management
51
+ SERVICE_START = "service.start"
52
+ SERVICE_STOP = "service.stop"
53
+ SERVICE_RESTART = "service.restart"
54
+ SERVICE_ENABLE = "service.enable"
55
+ SERVICE_DISABLE = "service.disable"
56
+ SERVICE_GET_STATUS = "service.get_status"
57
+ SERVICE_LIST = "service.list"
58
+ SERVICE_SUBSCRIBE = "service.subscribe"
59
+ SERVICE_UNSUBSCRIBE = "service.unsubscribe"
60
+
61
+ # System
62
+ SYSTEM_REBOOT = "system.reboot"
63
+ SYSTEM_SHUTDOWN = "system.shutdown"
64
+ SYSTEM_FIRMWARE_REBOOT = "system.firmware_reboot"
65
+ SYSTEM_DAEMON_RELOAD = "system.daemon_reload"
66
+ SYSTEM_SYNC = "system.sync"
67
+ SYSTEM_DROP_CACHES = "system.drop_caches"
68
+ SYSTEM_GET_PUBLIC_IP = "system.get_public_ip"
69
+ SYSTEM_CHECK_UEFI = "system.check_uefi"
70
+ SYSTEM_CHECK_LUKS = "system.check_luks"
71
+ SYSTEM_CHECK_CONNECTIVITY = "system.check_connectivity"
72
+ SYSTEM_GET_LOCAL_IP = "system.get_local_ip"
73
+
74
+ # Firewall
75
+ FIREWALL_ADD_RULE = "firewall.add_rule"
76
+ FIREWALL_REMOVE_RULE = "firewall.remove_rule"
77
+ FIREWALL_GET_RULES = "firewall.get_rules"
78
+
79
+ # Installation
80
+ INSTALL_START = "install.start"
81
+ INSTALL_GET_STATE = "install.get_state"
82
+ INSTALL_ABORT = "install.abort"
83
+ INSTALL_CANCEL = "install.cancel"
84
+
85
+ # Reinstall (post-installation)
86
+ REINSTALL_START = "reinstall.start"
87
+
88
+ # FluxD
89
+ FLUXD_GET_STATUS = "fluxd.get_status"
90
+ FLUXD_GET_BLOCK_HEIGHT = "fluxd.get_block_height"
91
+ FLUXD_GET_BLOCK_HEIGHT_API = "fluxd.get_block_height_api"
92
+ FLUXD_GET_INFO = "fluxd.get_info"
93
+ FLUXD_CALL_RPC = "fluxd.call_rpc"
94
+ FLUXD_TEST_DBS = "fluxd.test_dbs"
95
+ FLUXD_GET_BLOCKHEIGHT_FROM_DB = "fluxd.get_blockheight_from_db"
96
+ FLUXD_GET_BLOCK_COUNT = "fluxd.get_block_count"
97
+ FLUXD_ZMQ_STATUS = "fluxd.zmq_status"
98
+
99
+ # FluxBenchD
100
+ FLUXBENCHD_GET_STATUS = "fluxbenchd.get_status"
101
+ FLUXBENCHD_GET_BENCHMARKS = "fluxbenchd.get_benchmarks"
102
+ FLUXBENCHD_CALL_RPC = "fluxbenchd.call_rpc"
103
+
104
+ # Delegate Node Starting
105
+ DELEGATE_CHECK_READINESS = "delegate.check_readiness"
106
+ DELEGATE_VALIDATE_PASSWORD = "delegate.validate_password"
107
+ DELEGATE_START_NODE = "delegate.start_node"
108
+
109
+ # Node Operations
110
+ NODE_CLONE_REPO = "node.clone_repo"
111
+ NODE_NPM_INSTALL = "node.npm_install"
112
+ NODE_DOWNLOAD_CHAIN = "node.download_chain"
113
+ NODE_VERIFY_CHAIN = "node.verify_chain"
114
+ NODE_FETCH_PARAMS = "node.fetch_params"
115
+ NODE_GET_CHAIN_PROGRESS = "node.get_chain_progress"
116
+
117
+ # Bootstrap Operations
118
+ BOOTSTRAP_GET_FASTEST_CDN = "bootstrap.get_fastest_cdn"
119
+
120
+ # Upgrade Operations
121
+ UPGRADE_CHECK = "upgrade.check"
122
+ UPGRADE_START = "upgrade.start"
123
+ UPGRADE_GET_STATE = "upgrade.get_state"
124
+ UPGRADE_DEFER_REBOOT = "upgrade.defer_reboot"
125
+
126
+ # Reconfiguration
127
+ RECONFIGURE_SET_MODE = "reconfigure.set_mode"
128
+ RECONFIGURE_GET_STATE = "reconfigure.get_state"
129
+ RECONFIGURE_SERVICES = "reconfigure.services"
130
+ RECONFIGURE_START = "reconfigure.start"
131
+
132
+ # Display / X11
133
+ DISPLAY_SET_RESOLUTION = "display.set_resolution"
134
+ DISPLAY_SET_DPMS = "display.set_dpms"
135
+ DISPLAY_GET_RESOLUTIONS = "display.get_resolutions"
136
+
137
+ # Web API / Webserver
138
+ WEB_GET_TOKEN = "web.get_token" # noqa: S105
139
+ WEB_CONFIGURE = "web.configure"
140
+ WEBSERVER_START = "webserver.start"
141
+ WEBSERVER_STOP = "webserver.stop"
142
+ WEBSERVER_GET_STATUS = "webserver.get_status"
143
+
144
+ # Tunnel Management
145
+ TUNNEL_START = "tunnel.start"
146
+ TUNNEL_STOP = "tunnel.stop"
147
+ TUNNEL_GET_STATUS = "tunnel.get_status"
148
+
149
+ # System Metrics
150
+ METRICS_GET_SYSTEM_LOAD = "metrics.get_system_load"
151
+ METRICS_GET_MEMORY = "metrics.get_memory"
152
+ METRICS_GET_DISK = "metrics.get_disk"
153
+ METRICS_GET_CPU = "metrics.get_cpu"
154
+ METRICS_GET_NETWORK = "metrics.get_network"
155
+ METRICS_GET_PROCESS_MEMORY = "metrics.get_process_memory"
156
+
157
+ # Logs
158
+ LOGS_GET_SERVICE = "logs.get_service"
159
+ LOGS_GET_JOURNAL = "logs.get_journal"
160
+ LOGS_GET_AVAILABLE_SERVICES = "logs.get_available_services"
161
+
162
+ # Filesystem
163
+ FILESYSTEM_CREATE_DIRECTORIES = "filesystem.create_directories"
164
+ FILESYSTEM_REMOVE_DIRECTORIES = "filesystem.remove_directories"
165
+ FILESYSTEM_HASH_FILE = "filesystem.hash_file"
166
+
167
+ # Task Management (async operations)
168
+ TASK_GET_STATUS = "task.get_status"
169
+ TASK_LIST = "task.list"
170
+
171
+ # Network Interface Management
172
+ NETWORK_GET_INTERFACES = "network.get_interfaces"
173
+ NETWORK_SET_STATIC_IP = "network.set_static_ip"
174
+ NETWORK_SET_DHCP = "network.set_dhcp"
175
+ NETWORK_SET_DISABLED = "network.set_disabled"
176
+ NETWORK_CREATE_VLAN = "network.create_vlan"
177
+ NETWORK_DELETE_VLAN = "network.delete_vlan"
178
+ NETWORK_RESTART_NETWORKD = "network.restart_networkd"
179
+
180
+ # Network DNS
181
+ NETWORK_GET_DNS = "network.get_dns"
182
+ NETWORK_TEST_DNS = "network.test_dns"
183
+
184
+ # Network Routing
185
+ NETWORK_GET_ROUTES = "network.get_routes"
186
+ NETWORK_TEST_CONNECTIVITY = "network.test_connectivity"
187
+
188
+ # Network UPnP
189
+ NETWORK_UPNP_GET_STATUS = "network.upnp.get_status"
190
+ NETWORK_UPNP_GET_MAPPINGS = "network.upnp.get_mappings"
191
+ NETWORK_UPNP_ADD_MAPPING = "network.upnp.add_mapping"
192
+ NETWORK_UPNP_REMOVE_MAPPING = "network.upnp.remove_mapping"
193
+
194
+ # Network Traffic Shaping
195
+ NETWORK_SHAPING_GET_POLICY = "network.shaping.get_policy"
196
+ NETWORK_SHAPING_SET_POLICY = "network.shaping.set_policy"
197
+
198
+
199
+ class EventType(str, Enum):
200
+ """Event types (Daemon → Client)."""
201
+
202
+ # Service State
203
+ SERVICE_STATE_CHANGED = "service.state_changed"
204
+ SERVICE_STATES_READY = "service.states_ready"
205
+ SERVICE_STARTED = "service.started"
206
+ SERVICE_STOPPED = "service.stopped"
207
+
208
+ # Installation Progress
209
+ INSTALL_TASK_STARTED = "install.task_started"
210
+ INSTALL_TASK_COMPLETED = "install.task_completed"
211
+ INSTALL_TASK_CANCELLED = "install.task_cancelled"
212
+ INSTALL_TASK_FAILED = "install.task_failed"
213
+ INSTALL_PROGRESS = "install.progress"
214
+ INSTALL_STATE_CHANGED = "install.state_changed"
215
+
216
+ # Download Progress (chain, params)
217
+ DOWNLOAD_PROGRESS = "download.progress"
218
+ DOWNLOAD_COMPLETED = "download.completed"
219
+ DOWNLOAD_FAILED = "download.failed"
220
+
221
+ # Upgrade Events
222
+ UPGRADE_STARTED = "upgrade.started"
223
+ UPGRADE_IN_PROGRESS = "upgrade.in_progress" # Alias for UPGRADE_STARTED
224
+ UPGRADE_AVAILABLE = "upgrade.available"
225
+ UPGRADE_PROGRESS = "upgrade.progress"
226
+ UPGRADE_PROPERTY_CHANGED = "upgrade.property_changed"
227
+ UPGRADE_COMPLETED = "upgrade.completed"
228
+ UPGRADE_FAILED = "upgrade.failed"
229
+
230
+ # System Events
231
+ SYSTEM_CONNECTIVITY = "system.connectivity"
232
+ SYSTEM_PUBLIC_IP = "system.public_ip"
233
+ SYSTEM_ERROR = "system.error"
234
+ SYSTEM_METRICS_UPDATE = "system.metrics_update" # Periodic metrics (every 5s)
235
+ NETWORK_CONFIG_REQUIRED = "network.config_required"
236
+ INSUFFICIENT_SPACE = "system.insufficient_space"
237
+
238
+ # Network Events
239
+ NETWORK_INTERFACE_CHANGED = "network.interface_changed"
240
+ NETWORK_ROUTES_CHANGED = "network.routes_changed"
241
+ NETWORK_DNS_CHANGED = "network.dns_changed"
242
+ NETWORK_UPNP_STATUS_CHANGED = "network.upnp_status_changed"
243
+
244
+ # Network Monitoring Events (subscription-triggered)
245
+ CONNECTIVITY_UPDATE = "network.connectivity_update"
246
+ DNS_RESOLUTION_UPDATE = "network.dns_resolution_update"
247
+
248
+ # Fluxd Events
249
+ FLUXD_RPC_ONLINE = "fluxd.rpc_online"
250
+ FLUXD_RPC_OFFLINE = "fluxd.rpc_offline"
251
+ FLUXD_BLOCK_HEIGHT = "fluxd.block_height"
252
+ FLUXD_ZMQ_CONNECTED = "fluxd.zmq_connected"
253
+ FLUXD_ZMQ_DISCONNECTED = "fluxd.zmq_disconnected"
254
+ FLUXD_ZMQ_NEW_BLOCK = "fluxd.zmq_new_block"
255
+ FLUXD_STATUS_CHANGED = "fluxd.status_changed"
256
+ FLUXBENCHD_STATUS_CHANGED = "fluxbenchd.status_changed"
257
+
258
+ # Web Configuration
259
+ WEBSERVER_STARTED = "webserver.started"
260
+ WEBSERVER_STOPPED = "webserver.stopped"
261
+
262
+ # Tunnel Events
263
+ TUNNEL_CONNECTING = "tunnel.connecting"
264
+ TUNNEL_STARTED = "tunnel.started"
265
+ TUNNEL_STOPPED = "tunnel.stopped"
266
+ TUNNEL_ERROR = "tunnel.error"
267
+
268
+ # Log/Activity Messages
269
+ LOG_MESSAGE = "log.message"
270
+
271
+ # State Synchronization
272
+ STATE_UPDATE = "state.update" # Unified state update event
273
+ INITIAL_STATE = "state.initial" # Complete state sent to new clients
274
+
275
+ # Async Task Events (for long-running operations)
276
+ TASK_STARTED = "task.started"
277
+ TASK_PROGRESS = "task.progress"
278
+ TASK_COMPLETED = "task.completed"
279
+ TASK_FAILED = "task.failed"
280
+
281
+
282
+ class RPCErrorCode(int, Enum):
283
+ """JSON-RPC 2.0 error codes."""
284
+
285
+ PARSE_ERROR = -32700
286
+ INVALID_REQUEST = -32600
287
+ METHOD_NOT_FOUND = -32601
288
+ INVALID_PARAMS = -32602
289
+ INTERNAL_ERROR = -32603
290
+
291
+ # Custom error codes
292
+ UNAUTHORIZED = -32000
293
+ SERVICE_NOT_FOUND = -32001
294
+ INSTALLATION_IN_PROGRESS = -32002
295
+ INSTALLATION_FAILED = -32003
296
+ PRIVILEGE_ERROR = -32004
297
+
298
+
299
+ class JsonRpcRequest(BaseModel):
300
+ """JSON-RPC 2.0 request message."""
301
+
302
+ jsonrpc: str = Field(default="2.0", description="JSON-RPC version")
303
+ method: str = Field(description="Method name")
304
+ params: dict[str, Any] | list[Any] | None = Field(default=None, description="Method parameters")
305
+ id: str | int | None = Field(default=None, description="Request ID")
306
+
307
+
308
+ class JsonRpcError(BaseModel):
309
+ """JSON-RPC 2.0 error object."""
310
+
311
+ code: int = Field(description="Error code")
312
+ message: str = Field(description="Error message")
313
+ data: Any | None = Field(default=None, description="Additional error data")
314
+
315
+
316
+ class JsonRpcResponse(BaseModel):
317
+ """JSON-RPC 2.0 response message."""
318
+
319
+ jsonrpc: str = Field(default="2.0", description="JSON-RPC version")
320
+ result: Any | None = Field(default=None, description="Method result")
321
+ error: JsonRpcError | None = Field(default=None, description="Error object")
322
+ id: str | int | None = Field(default=None, description="Request ID")
323
+
324
+
325
+ class Event(BaseModel):
326
+ """Event message (Daemon → Client)."""
327
+
328
+ type: str = Field(description="Event type")
329
+ data: dict[str, Any] = Field(description="Event data")
330
+ timestamp: float = Field(description="Event timestamp (Unix time)")
331
+
332
+
333
+ # --- Data Models ---
334
+
335
+
336
+ class ServiceStatusData(BaseModel):
337
+ """Service status data."""
338
+
339
+ name: str
340
+ active: bool
341
+ running: bool
342
+ enabled: bool
343
+ pid: int | None = None
344
+ error: str | None = None
345
+
346
+
347
+ class InstallStateData(BaseModel):
348
+ """Installation state data."""
349
+
350
+ in_progress: bool
351
+ current_task: str | None = None
352
+ completed_tasks: list[str]
353
+ failed_task: str | None = None
354
+ error: str | None = None
355
+
356
+
357
+ class UpgradeStateData(BaseModel):
358
+ """Upgrade state data - maps to D-Bus FluxUpgrade1 properties."""
359
+
360
+ validating: bool = False
361
+ available: bool = False
362
+ in_progress: bool = False
363
+ bytes_complete: int = 0
364
+ bytes_total: int = 0
365
+ start_time: float = 0.0
366
+ finish_time: float = 0.0
367
+ attempts: int = 0
368
+ reboot_deferred: bool = False
369
+ reboot_timer: int = 0
370
+ current_version: str | None = None
371
+ new_version: str | None = None
372
+
373
+ @property
374
+ def in_flight(self) -> bool:
375
+ """Check if any upgrade activity is in progress."""
376
+ return self.validating or self.available or self.in_progress
377
+
378
+ @property
379
+ def progress(self) -> float | None:
380
+ """Calculate progress as a percentage (0.0 to 1.0)."""
381
+ if self.bytes_total > 0:
382
+ return self.bytes_complete / self.bytes_total
383
+ return None
384
+
385
+
386
+ class DownloadProgressData(BaseModel):
387
+ """Download progress data."""
388
+
389
+ file: str
390
+ bytes_downloaded: int
391
+ total_bytes: int | None = None
392
+ percent: float | None = None
393
+ speed_mbps: float | None = None
394
+
395
+
396
+ class FluxdStatusData(BaseModel):
397
+ """Fluxd RPC status data."""
398
+
399
+ online: bool
400
+ block_height: int | None = None
401
+ connections: int | None = None
402
+ synced: bool | None = None