golem-vm-provider 0.1.8__py3-none-any.whl → 0.1.10__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.
- {golem_vm_provider-0.1.8.dist-info → golem_vm_provider-0.1.10.dist-info}/METADATA +99 -87
- {golem_vm_provider-0.1.8.dist-info → golem_vm_provider-0.1.10.dist-info}/RECORD +6 -6
- provider/config.py +1 -1
- provider/vm/port_manager.py +56 -47
- {golem_vm_provider-0.1.8.dist-info → golem_vm_provider-0.1.10.dist-info}/WHEEL +0 -0
- {golem_vm_provider-0.1.8.dist-info → golem_vm_provider-0.1.10.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: golem-vm-provider
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.10
|
4
4
|
Summary: VM on Golem Provider Node - Run your own provider node to offer VMs on the Golem Network
|
5
5
|
Keywords: golem,vm,provider,cloud,decentralized
|
6
6
|
Author: Phillip Jensen
|
@@ -82,20 +82,20 @@ sequenceDiagram
|
|
82
82
|
PM-->>S: Verification Result
|
83
83
|
```
|
84
84
|
|
85
|
-
-
|
86
|
-
-
|
87
|
-
-
|
88
|
-
-
|
85
|
+
- Comprehensive port accessibility verification
|
86
|
+
- Real-time status display with progress indicators
|
87
|
+
- Local and external port validation
|
88
|
+
- Automatic port allocation management
|
89
89
|
|
90
90
|
### Future Developments
|
91
91
|
|
92
92
|
The current port verification system uses dedicated port check servers to verify external accessibility. In future releases, this functionality will be integrated into the Golem Network's verifier nodes, providing:
|
93
93
|
|
94
|
-
-
|
95
|
-
-
|
96
|
-
-
|
97
|
-
-
|
98
|
-
-
|
94
|
+
- Decentralized port verification through the network
|
95
|
+
- Increased reliability with multiple verification sources
|
96
|
+
- Consensus-based verification results
|
97
|
+
- Reduced dependency on centralized services
|
98
|
+
- Enhanced security through the network's trust system
|
99
99
|
|
100
100
|
This integration aligns with Golem's vision of a fully decentralized computing platform, moving critical infrastructure services like port verification into the network itself.
|
101
101
|
|
@@ -103,10 +103,10 @@ This integration aligns with Golem's vision of a fully decentralized computing p
|
|
103
103
|
|
104
104
|
The resource management system ensures optimal allocation and utilization of system resources:
|
105
105
|
|
106
|
-
-
|
107
|
-
-
|
108
|
-
-
|
109
|
-
-
|
106
|
+
- Real-time monitoring of CPU, memory, and storage
|
107
|
+
- Intelligent resource allocation with minimum requirement enforcement
|
108
|
+
- Threshold-based resource protection
|
109
|
+
- Automatic resource reclamation
|
110
110
|
|
111
111
|
```mermaid
|
112
112
|
sequenceDiagram
|
@@ -114,7 +114,7 @@ sequenceDiagram
|
|
114
114
|
participant RT as Resource Tracker
|
115
115
|
participant RM as Resource Monitor
|
116
116
|
participant AD as Advertiser
|
117
|
-
|
117
|
+
|
118
118
|
API->>RT: Request Resource Allocation
|
119
119
|
RT->>RM: Check Available Resources
|
120
120
|
RM-->>RT: Resource Status
|
@@ -134,7 +134,7 @@ sequenceDiagram
|
|
134
134
|
participant MP as Multipass
|
135
135
|
participant CI as Cloud Init
|
136
136
|
participant VM as Virtual Machine
|
137
|
-
|
137
|
+
|
138
138
|
API->>MP: Create VM Request
|
139
139
|
MP->>CI: Generate Config
|
140
140
|
CI-->>MP: SSH Configuration
|
@@ -143,10 +143,10 @@ sequenceDiagram
|
|
143
143
|
MP-->>API: VM Info
|
144
144
|
```
|
145
145
|
|
146
|
-
-
|
147
|
-
-
|
148
|
-
-
|
149
|
-
-
|
146
|
+
- Automated VM provisioning with cloud-init
|
147
|
+
- Secure SSH key management
|
148
|
+
- Status monitoring and health checks
|
149
|
+
- Automatic cleanup procedures
|
150
150
|
|
151
151
|
### Network Proxy System
|
152
152
|
|
@@ -158,7 +158,7 @@ sequenceDiagram
|
|
158
158
|
participant PM as Proxy Manager
|
159
159
|
participant P as Proxy
|
160
160
|
participant VM as Virtual Machine
|
161
|
-
|
161
|
+
|
162
162
|
C->>PM: SSH Connection
|
163
163
|
PM->>P: Create Proxy
|
164
164
|
P->>VM: Forward Connection
|
@@ -166,29 +166,31 @@ sequenceDiagram
|
|
166
166
|
P-->>C: Forward Response
|
167
167
|
```
|
168
168
|
|
169
|
-
-
|
170
|
-
-
|
171
|
-
-
|
172
|
-
-
|
169
|
+
- Dynamic port allocation and management
|
170
|
+
- Connection state persistence
|
171
|
+
- Clean connection handling
|
172
|
+
- Automatic proxy cleanup
|
173
173
|
|
174
174
|
## Installation
|
175
175
|
|
176
176
|
1. Prerequisites:
|
177
|
-
|
178
|
-
|
179
|
-
|
177
|
+
|
178
|
+
- Python 3.9+
|
179
|
+
- Multipass
|
180
|
+
- Poetry
|
180
181
|
|
181
182
|
2. Install dependencies:
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
183
|
+
|
184
|
+
```bash
|
185
|
+
cd provider-server
|
186
|
+
poetry install
|
187
|
+
```
|
186
188
|
|
187
189
|
3. Configure environment:
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
190
|
+
```bash
|
191
|
+
cp .env.example .env
|
192
|
+
# Edit .env with your settings
|
193
|
+
```
|
192
194
|
|
193
195
|
## Configuration
|
194
196
|
|
@@ -219,7 +221,7 @@ GOLEM_PROVIDER_PORT_RANGE_END={end_port} # Default: 50900
|
|
219
221
|
GOLEM_PROVIDER_PUBLIC_IP="auto"
|
220
222
|
|
221
223
|
# Discovery Settings
|
222
|
-
GOLEM_PROVIDER_DISCOVERY_URL="http://discovery.golem.network:
|
224
|
+
GOLEM_PROVIDER_DISCOVERY_URL="http://discovery.golem.network:9001"
|
223
225
|
GOLEM_PROVIDER_ADVERTISEMENT_INTERVAL=240
|
224
226
|
```
|
225
227
|
|
@@ -232,6 +234,7 @@ POST /api/v1/vms
|
|
232
234
|
```
|
233
235
|
|
234
236
|
Request:
|
237
|
+
|
235
238
|
```json
|
236
239
|
{
|
237
240
|
"name": "my-webserver",
|
@@ -242,6 +245,7 @@ Request:
|
|
242
245
|
```
|
243
246
|
|
244
247
|
Response:
|
248
|
+
|
245
249
|
```json
|
246
250
|
{
|
247
251
|
"id": "golem-my-webserver-20250219-130424",
|
@@ -259,10 +263,10 @@ Response:
|
|
259
263
|
|
260
264
|
### VM Operations
|
261
265
|
|
262
|
-
-
|
263
|
-
-
|
264
|
-
-
|
265
|
-
-
|
266
|
+
- List VMs: `GET /api/v1/vms`
|
267
|
+
- Get VM Status: `GET /api/v1/vms/{vm_id}`
|
268
|
+
- Delete VM: `DELETE /api/v1/vms/{vm_id}`
|
269
|
+
- Get Access Info: `GET /api/v1/vms/{vm_id}/access`
|
266
270
|
|
267
271
|
## Operations
|
268
272
|
|
@@ -273,10 +277,11 @@ poetry run python run.py
|
|
273
277
|
```
|
274
278
|
|
275
279
|
The provider will:
|
280
|
+
|
276
281
|
1. Verify port accessibility
|
277
|
-
|
278
|
-
|
279
|
-
|
282
|
+
- Check discovery port (7466)
|
283
|
+
- Verify SSH ports (50800-50900)
|
284
|
+
- Display verification progress
|
280
285
|
2. Initialize resource monitoring
|
281
286
|
3. Start the proxy manager
|
282
287
|
4. Begin resource advertisement
|
@@ -290,7 +295,7 @@ sequenceDiagram
|
|
290
295
|
participant RT as Resource Tracker
|
291
296
|
participant AD as Advertiser
|
292
297
|
participant DS as Discovery Service
|
293
|
-
|
298
|
+
|
294
299
|
P->>RT: Initialize
|
295
300
|
RT->>AD: Register Callback
|
296
301
|
loop Every 4 minutes
|
@@ -304,33 +309,34 @@ sequenceDiagram
|
|
304
309
|
### Monitoring
|
305
310
|
|
306
311
|
The provider includes comprehensive logging:
|
307
|
-
|
308
|
-
-
|
309
|
-
-
|
310
|
-
-
|
312
|
+
|
313
|
+
- Resource allocation events
|
314
|
+
- VM lifecycle changes
|
315
|
+
- Network proxy operations
|
316
|
+
- Discovery service interactions
|
311
317
|
|
312
318
|
## Technical Details
|
313
319
|
|
314
320
|
### Security
|
315
321
|
|
316
|
-
-
|
317
|
-
-
|
318
|
-
-
|
319
|
-
-
|
322
|
+
- Resource isolation through Multipass
|
323
|
+
- Secure SSH key provisioning
|
324
|
+
- Connection proxying for network isolation
|
325
|
+
- Rate limiting on API endpoints
|
320
326
|
|
321
327
|
### Performance
|
322
328
|
|
323
|
-
-
|
324
|
-
-
|
325
|
-
-
|
326
|
-
-
|
329
|
+
- Asynchronous operations with FastAPI
|
330
|
+
- Efficient resource tracking
|
331
|
+
- Connection pooling for proxy servers
|
332
|
+
- Optimized VM provisioning
|
327
333
|
|
328
334
|
### Resource Protection
|
329
335
|
|
330
|
-
-
|
331
|
-
-
|
332
|
-
-
|
333
|
-
-
|
336
|
+
- CPU threshold: 90%
|
337
|
+
- Memory threshold: 85%
|
338
|
+
- Storage threshold: 90%
|
339
|
+
- Minimum resource guarantees
|
334
340
|
|
335
341
|
## Troubleshooting
|
336
342
|
|
@@ -339,33 +345,37 @@ Common issues and solutions:
|
|
339
345
|
### Port Verification Issues
|
340
346
|
|
341
347
|
1. Provider Port ({provider_port}) Issues
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
348
|
+
|
349
|
+
- Check if port is already in use
|
350
|
+
- Verify port forwarding on router
|
351
|
+
- Check firewall rules
|
352
|
+
- Ensure provider is accessible to requestors
|
346
353
|
|
347
354
|
2. VM Access Port Range ({start_port}-{end_port}) Issues
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
355
|
+
|
356
|
+
- Verify port range availability
|
357
|
+
- Check for port conflicts
|
358
|
+
- Configure router port forwarding
|
359
|
+
- Review firewall settings for range
|
352
360
|
|
353
361
|
3. External Access Issues
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
362
|
+
- Verify internet connectivity
|
363
|
+
- Check port check servers are accessible
|
364
|
+
- Review router NAT/firewall settings
|
365
|
+
- Consider using alternative port check servers
|
358
366
|
|
359
367
|
### Port Verification Monitoring
|
360
368
|
|
361
369
|
The provider includes real-time port verification status:
|
362
|
-
|
363
|
-
-
|
364
|
-
-
|
365
|
-
-
|
366
|
-
-
|
370
|
+
|
371
|
+
- Visual progress indicators
|
372
|
+
- Port accessibility status
|
373
|
+
- Critical issues detection
|
374
|
+
- Quick fix suggestions
|
375
|
+
- Links to troubleshooting documentation
|
367
376
|
|
368
377
|
Example status output:
|
378
|
+
|
369
379
|
```bash
|
370
380
|
🌟 Port Verification Status
|
371
381
|
==========================
|
@@ -376,17 +386,19 @@ Example status output:
|
|
376
386
|
```
|
377
387
|
|
378
388
|
### Resource Allocation Issues
|
379
|
-
|
380
|
-
-
|
381
|
-
-
|
382
|
-
-
|
389
|
+
|
390
|
+
- Check system resource availability
|
391
|
+
- Verify minimum requirements
|
392
|
+
- Monitor resource thresholds
|
393
|
+
- Review resource allocation logs
|
383
394
|
|
384
395
|
### Discovery Service Issues
|
385
|
-
|
386
|
-
-
|
387
|
-
-
|
388
|
-
-
|
389
|
-
-
|
396
|
+
|
397
|
+
- Check network connectivity
|
398
|
+
- Verify discovery service URL
|
399
|
+
- Check advertisement interval
|
400
|
+
- Monitor advertisement responses
|
401
|
+
- Verify provider registration status
|
390
402
|
|
391
403
|
## Contributing
|
392
404
|
|
@@ -2,7 +2,7 @@ provider/__init__.py,sha256=HO1fkPpZqPO3z8O8-eVIyx8xXSMIVuTR_b1YF0RtXOg,45
|
|
2
2
|
provider/api/__init__.py,sha256=ssX1ugDqEPt8Fn04IymgmG-Ev8PiXLsCSaiZVvHQnec,344
|
3
3
|
provider/api/models.py,sha256=JOzoNf1oE5N97UqTN5xuIrTkqn2tCHqPDaIzGA3jUyo,3513
|
4
4
|
provider/api/routes.py,sha256=P27RQvNqFWn6PacRwr1PaVz-yv5KAWsp9KeORejkXSI,6452
|
5
|
-
provider/config.py,sha256=
|
5
|
+
provider/config.py,sha256=vEYg-DxijleAwqfyjCHM6OLK1pmj6hzG75jrHvco3p4,5005
|
6
6
|
provider/discovery/__init__.py,sha256=VR3NRoQtZRH5Vs8FG7jnGLR7p7wn7XeZdLaBb3t8e1g,123
|
7
7
|
provider/discovery/advertiser.py,sha256=yv7RbRf1K43qOLAEa2Olj9hhN8etl2qsBuoHok0xoVs,6784
|
8
8
|
provider/discovery/resource_tracker.py,sha256=8dYhJxoe_jLRwisHoA0jr575YhUKmLIqSXfW88KshcQ,6000
|
@@ -18,9 +18,9 @@ provider/vm/cloud_init.py,sha256=o2CWLjl1ZN9fSEFHAWO-glh7BW-DxAMSe0MbqhzKNTg,170
|
|
18
18
|
provider/vm/models.py,sha256=zkfvP5Z50SPDNajwZTt9NTDIMRQIsZLvSOsuirHEcJM,6256
|
19
19
|
provider/vm/multipass.py,sha256=RLUqCeoYz4PG8RL7dBu_TzjNEAmgIz9NonBtSuYc4kw,16431
|
20
20
|
provider/vm/name_mapper.py,sha256=MrshNeJ4Dw-WBsyiIVcn9N5xyOxaBKX4Yqhyh_m5IFg,4103
|
21
|
-
provider/vm/port_manager.py,sha256=
|
21
|
+
provider/vm/port_manager.py,sha256=d03uwU76vx6LgADMN8ffBT9t400XQ3vtYlXr6cLIFN0,9831
|
22
22
|
provider/vm/proxy_manager.py,sha256=cu0FPPbeCc3CR6NRE_CnLjiRg7xVdSFUylVUOL1g1sI,10154
|
23
|
-
golem_vm_provider-0.1.
|
24
|
-
golem_vm_provider-0.1.
|
25
|
-
golem_vm_provider-0.1.
|
26
|
-
golem_vm_provider-0.1.
|
23
|
+
golem_vm_provider-0.1.10.dist-info/METADATA,sha256=QLachbvexsgzxaUKfGG_Ckzme9OJJ2Z4iS4wfUW3lpA,10594
|
24
|
+
golem_vm_provider-0.1.10.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
25
|
+
golem_vm_provider-0.1.10.dist-info/entry_points.txt,sha256=E4rCWo_Do_2zCG_GewNuftfVlHF_8b_OvioZre0dfeA,54
|
26
|
+
golem_vm_provider-0.1.10.dist-info/RECORD,,
|
provider/config.py
CHANGED
@@ -45,7 +45,7 @@ class Settings(BaseSettings):
|
|
45
45
|
return identity.get_or_create_identity()
|
46
46
|
|
47
47
|
# Discovery Service Settings
|
48
|
-
DISCOVERY_URL: str = "http://
|
48
|
+
DISCOVERY_URL: str = "http://195.201.39.101:9001"
|
49
49
|
ADVERTISEMENT_INTERVAL: int = 240 # seconds
|
50
50
|
|
51
51
|
# VM Settings
|
provider/vm/port_manager.py
CHANGED
@@ -13,9 +13,10 @@ from ..utils.port_display import PortVerificationDisplay
|
|
13
13
|
|
14
14
|
logger = logging.getLogger(__name__)
|
15
15
|
|
16
|
+
|
16
17
|
class PortManager:
|
17
18
|
"""Manages port allocation and verification for VM SSH proxying."""
|
18
|
-
|
19
|
+
|
19
20
|
def __init__(
|
20
21
|
self,
|
21
22
|
start_port: int = 50800,
|
@@ -25,7 +26,7 @@ class PortManager:
|
|
25
26
|
discovery_port: Optional[int] = None
|
26
27
|
):
|
27
28
|
"""Initialize the port manager.
|
28
|
-
|
29
|
+
|
29
30
|
Args:
|
30
31
|
start_port: Beginning of port range
|
31
32
|
end_port: End of port range (exclusive)
|
@@ -34,49 +35,50 @@ class PortManager:
|
|
34
35
|
"""
|
35
36
|
self.start_port = start_port
|
36
37
|
self.end_port = end_port
|
37
|
-
self.state_file = state_file or os.path.expanduser(
|
38
|
+
self.state_file = state_file or os.path.expanduser(
|
39
|
+
"~/.golem/provider/ports.json")
|
38
40
|
self.lock = Lock()
|
39
41
|
self._used_ports: dict[str, int] = {} # vm_id -> port
|
40
42
|
self.verified_ports: Set[int] = set()
|
41
|
-
|
43
|
+
|
42
44
|
# Initialize port verifier with default servers
|
43
45
|
self.port_check_servers = port_check_servers or [
|
44
46
|
"http://localhost:9000", # Local development server
|
45
|
-
"http://
|
46
|
-
|
47
|
-
"http://portcheck3.golem.network:7466"
|
47
|
+
"http://195.201.39.101:9000", # Production servers
|
48
|
+
|
48
49
|
]
|
49
50
|
self.discovery_port = discovery_port or settings.PORT
|
50
51
|
self.port_verifier = PortVerifier(
|
51
52
|
self.port_check_servers,
|
52
53
|
discovery_port=self.discovery_port
|
53
54
|
)
|
54
|
-
|
55
|
+
|
55
56
|
self._load_state()
|
56
|
-
|
57
|
+
|
57
58
|
async def initialize(self) -> bool:
|
58
59
|
"""Initialize port manager with verification.
|
59
|
-
|
60
|
+
|
60
61
|
Returns:
|
61
62
|
bool: True if required ports were verified successfully
|
62
63
|
"""
|
63
64
|
from ..config import settings
|
64
|
-
|
65
|
+
|
65
66
|
display = PortVerificationDisplay(
|
66
67
|
provider_port=self.discovery_port,
|
67
68
|
port_range_start=self.start_port,
|
68
69
|
port_range_end=self.end_port
|
69
70
|
)
|
70
71
|
display.print_header()
|
71
|
-
|
72
|
+
|
72
73
|
# Only verify SSH ports since provider port was already verified
|
73
74
|
ssh_ports = list(range(self.start_port, self.end_port))
|
74
75
|
logger.info(f"Starting port verification...")
|
75
76
|
logger.info(f"SSH ports range: {self.start_port}-{self.end_port}")
|
76
|
-
logger.info(
|
77
|
-
|
77
|
+
logger.info(
|
78
|
+
f"Using port check servers: {', '.join(self.port_check_servers)}")
|
79
|
+
|
78
80
|
results = await self.port_verifier.verify_ports(ssh_ports)
|
79
|
-
|
81
|
+
|
80
82
|
# Add provider port as verified since we already checked it
|
81
83
|
results[self.discovery_port] = PortVerificationResult(
|
82
84
|
port=self.discovery_port,
|
@@ -84,7 +86,7 @@ class PortManager:
|
|
84
86
|
verified_by="local_verification",
|
85
87
|
attempts=[ServerAttempt(server="local_verification", success=True)]
|
86
88
|
)
|
87
|
-
|
89
|
+
|
88
90
|
# Check if discovery port was verified
|
89
91
|
if self.discovery_port not in results:
|
90
92
|
error_msg = f"Port {self.discovery_port} verification failed"
|
@@ -102,36 +104,39 @@ class PortManager:
|
|
102
104
|
# Display discovery port status with animation
|
103
105
|
discovery_result = results[self.discovery_port]
|
104
106
|
await display.print_discovery_status(discovery_result)
|
105
|
-
|
107
|
+
|
106
108
|
if not discovery_result.accessible:
|
107
109
|
error_msg = discovery_result.error or f"Port {self.discovery_port} is not accessible"
|
108
110
|
logger.error(f"Failed to verify discovery port: {error_msg}")
|
109
111
|
# Print summary before returning
|
110
112
|
display.print_summary(discovery_result, {})
|
111
113
|
return False
|
112
|
-
|
114
|
+
|
113
115
|
# Display SSH ports status with animation
|
114
|
-
ssh_results = {port: result for port,
|
116
|
+
ssh_results = {port: result for port,
|
117
|
+
result in results.items() if port != self.discovery_port}
|
115
118
|
await display.print_ssh_status(ssh_results)
|
116
|
-
|
119
|
+
|
117
120
|
# Store verified ports
|
118
|
-
self.verified_ports = {
|
119
|
-
|
121
|
+
self.verified_ports = {
|
122
|
+
port for port, result in ssh_results.items() if result.accessible}
|
123
|
+
|
120
124
|
# Only show critical issues and quick fix if there are problems
|
121
125
|
if not discovery_result.accessible or not self.verified_ports:
|
122
126
|
display.print_critical_issues(discovery_result, ssh_results)
|
123
127
|
display.print_quick_fix(discovery_result, ssh_results)
|
124
|
-
|
128
|
+
|
125
129
|
# Print precise summary of current status
|
126
130
|
display.print_summary(discovery_result, ssh_results)
|
127
|
-
|
131
|
+
|
128
132
|
if not self.verified_ports:
|
129
133
|
logger.error("No SSH ports were verified as accessible")
|
130
134
|
return False
|
131
|
-
|
132
|
-
logger.info(
|
135
|
+
|
136
|
+
logger.info(
|
137
|
+
f"Successfully verified {len(self.verified_ports)} SSH ports")
|
133
138
|
return True
|
134
|
-
|
139
|
+
|
135
140
|
def _load_state(self) -> None:
|
136
141
|
"""Load port assignments from state file."""
|
137
142
|
try:
|
@@ -139,14 +144,15 @@ class PortManager:
|
|
139
144
|
if state_path.exists():
|
140
145
|
with open(state_path, 'r') as f:
|
141
146
|
self._used_ports = json.load(f)
|
142
|
-
logger.info(
|
147
|
+
logger.info(
|
148
|
+
f"Loaded port assignments for {len(self._used_ports)} VMs")
|
143
149
|
else:
|
144
150
|
state_path.parent.mkdir(parents=True, exist_ok=True)
|
145
151
|
self._save_state()
|
146
152
|
except Exception as e:
|
147
153
|
logger.error(f"Failed to load port state: {e}")
|
148
154
|
self._used_ports = {}
|
149
|
-
|
155
|
+
|
150
156
|
def _save_state(self) -> None:
|
151
157
|
"""Save current port assignments to state file."""
|
152
158
|
try:
|
@@ -154,17 +160,17 @@ class PortManager:
|
|
154
160
|
json.dump(self._used_ports, f)
|
155
161
|
except Exception as e:
|
156
162
|
logger.error(f"Failed to save port state: {e}")
|
157
|
-
|
163
|
+
|
158
164
|
def _get_used_ports(self) -> Set[int]:
|
159
165
|
"""Get set of currently used ports."""
|
160
166
|
return set(self._used_ports.values())
|
161
|
-
|
167
|
+
|
162
168
|
def allocate_port(self, vm_id: str) -> Optional[int]:
|
163
169
|
"""Allocate a verified port for a VM.
|
164
|
-
|
170
|
+
|
165
171
|
Args:
|
166
172
|
vm_id: Unique identifier for the VM
|
167
|
-
|
173
|
+
|
168
174
|
Returns:
|
169
175
|
Allocated port number or None if allocation failed
|
170
176
|
"""
|
@@ -175,11 +181,12 @@ class PortManager:
|
|
175
181
|
if port in self.verified_ports:
|
176
182
|
# Quick check if port is still available
|
177
183
|
try:
|
178
|
-
sock = socket.socket(
|
184
|
+
sock = socket.socket(
|
185
|
+
socket.AF_INET, socket.SOCK_STREAM)
|
179
186
|
sock.settimeout(1)
|
180
187
|
result = sock.connect_ex(('127.0.0.1', port))
|
181
188
|
sock.close()
|
182
|
-
|
189
|
+
|
183
190
|
if result != 0: # Port is available
|
184
191
|
return port
|
185
192
|
else:
|
@@ -193,23 +200,25 @@ class PortManager:
|
|
193
200
|
else:
|
194
201
|
# Previously allocated port is no longer verified
|
195
202
|
self._used_ports.pop(vm_id)
|
196
|
-
|
203
|
+
|
197
204
|
used_ports = self._get_used_ports()
|
198
|
-
|
205
|
+
|
199
206
|
# Find first available verified port
|
200
207
|
for port in sorted(self.verified_ports):
|
201
208
|
if port not in used_ports:
|
202
209
|
# Quick check if port is actually available
|
203
210
|
try:
|
204
|
-
sock = socket.socket(
|
211
|
+
sock = socket.socket(
|
212
|
+
socket.AF_INET, socket.SOCK_STREAM)
|
205
213
|
sock.settimeout(1)
|
206
214
|
result = sock.connect_ex(('127.0.0.1', port))
|
207
215
|
sock.close()
|
208
|
-
|
216
|
+
|
209
217
|
if result != 0: # Port is available
|
210
218
|
self._used_ports[vm_id] = port
|
211
219
|
self._save_state()
|
212
|
-
logger.info(
|
220
|
+
logger.info(
|
221
|
+
f"Allocated verified port {port} for VM {vm_id}")
|
213
222
|
return port
|
214
223
|
else:
|
215
224
|
# Port is in use, remove from verified ports
|
@@ -217,13 +226,13 @@ class PortManager:
|
|
217
226
|
except Exception as e:
|
218
227
|
logger.debug(f"Failed to check port {port}: {e}")
|
219
228
|
continue
|
220
|
-
|
229
|
+
|
221
230
|
logger.error("No verified ports available for allocation")
|
222
231
|
return None
|
223
|
-
|
232
|
+
|
224
233
|
def deallocate_port(self, vm_id: str) -> None:
|
225
234
|
"""Release a port allocation for a VM.
|
226
|
-
|
235
|
+
|
227
236
|
Args:
|
228
237
|
vm_id: Unique identifier for the VM
|
229
238
|
"""
|
@@ -232,18 +241,18 @@ class PortManager:
|
|
232
241
|
port = self._used_ports.pop(vm_id)
|
233
242
|
self._save_state()
|
234
243
|
logger.info(f"Deallocated port {port} for VM {vm_id}")
|
235
|
-
|
244
|
+
|
236
245
|
def get_port(self, vm_id: str) -> Optional[int]:
|
237
246
|
"""Get currently allocated port for a VM.
|
238
|
-
|
247
|
+
|
239
248
|
Args:
|
240
249
|
vm_id: Unique identifier for the VM
|
241
|
-
|
250
|
+
|
242
251
|
Returns:
|
243
252
|
Port number or None if VM has no allocation
|
244
253
|
"""
|
245
254
|
return self._used_ports.get(vm_id)
|
246
|
-
|
255
|
+
|
247
256
|
def cleanup(self) -> None:
|
248
257
|
"""Remove all port allocations."""
|
249
258
|
with self.lock:
|
File without changes
|
File without changes
|