golem-vm-provider 0.1.18__tar.gz → 0.1.20__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 (26) hide show
  1. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/PKG-INFO +1 -1
  2. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/main.py +6 -2
  3. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/vm/multipass.py +4 -1
  4. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/vm/proxy_manager.py +43 -21
  5. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/pyproject.toml +1 -1
  6. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/README.md +0 -0
  7. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/__init__.py +0 -0
  8. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/api/__init__.py +0 -0
  9. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/api/models.py +0 -0
  10. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/api/routes.py +0 -0
  11. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/config.py +0 -0
  12. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/discovery/__init__.py +0 -0
  13. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/discovery/advertiser.py +0 -0
  14. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/discovery/resource_tracker.py +0 -0
  15. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/network/port_verifier.py +0 -0
  16. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/security/ethereum.py +0 -0
  17. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/utils/ascii_art.py +0 -0
  18. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/utils/logging.py +0 -0
  19. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/utils/port_display.py +0 -0
  20. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/utils/retry.py +0 -0
  21. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/utils/setup.py +0 -0
  22. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/vm/__init__.py +0 -0
  23. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/vm/cloud_init.py +0 -0
  24. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/vm/models.py +0 -0
  25. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/vm/name_mapper.py +0 -0
  26. {golem_vm_provider-0.1.18 → golem_vm_provider-0.1.20}/provider/vm/port_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: golem-vm-provider
3
- Version: 0.1.18
3
+ Version: 0.1.20
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
@@ -31,11 +31,15 @@ async def setup_provider() -> None:
31
31
  provider = MultipassProvider(resource_tracker, port_manager=port_manager)
32
32
  try:
33
33
  await asyncio.wait_for(provider.initialize(), timeout=30)
34
- app.state.provider = provider
35
34
 
36
- # Store proxy manager reference for cleanup
35
+ # Store provider and proxy manager references
36
+ app.state.provider = provider
37
37
  app.state.proxy_manager = provider.proxy_manager
38
38
 
39
+ # Restore proxy configurations
40
+ logger.process("🔄 Restoring proxy configurations...")
41
+ await app.state.proxy_manager._load_state()
42
+
39
43
  except asyncio.TimeoutError:
40
44
  logger.error("Provider initialization timed out")
41
45
  raise
@@ -37,8 +37,11 @@ class MultipassProvider(VMProvider):
37
37
  self.vm_data_dir.mkdir(parents=True, exist_ok=True)
38
38
 
39
39
  # Initialize managers
40
- self.proxy_manager = PythonProxyManager(port_manager=port_manager)
41
40
  self.name_mapper = VMNameMapper(self.vm_data_dir / "vm_names.json")
41
+ self.proxy_manager = PythonProxyManager(
42
+ port_manager=port_manager,
43
+ name_mapper=self.name_mapper
44
+ )
42
45
 
43
46
  def _verify_installation(self) -> None:
44
47
  """Verify multipass is installed and get version."""
@@ -147,42 +147,64 @@ class PythonProxyManager:
147
147
  def __init__(
148
148
  self,
149
149
  port_manager: PortManager,
150
+ name_mapper: "VMNameMapper",
150
151
  state_file: Optional[str] = None
151
152
  ):
152
153
  """Initialize the proxy manager.
153
154
 
154
155
  Args:
155
156
  port_manager: Port allocation manager
157
+ name_mapper: VM name mapping manager
156
158
  state_file: Path to persist proxy state
157
159
  """
158
160
  self.port_manager = port_manager
161
+ self.name_mapper = name_mapper
159
162
  self.state_file = state_file or os.path.expanduser("~/.golem/provider/proxy_state.json")
160
- self._proxies: Dict[str, ProxyServer] = {} # vm_id -> ProxyServer
161
- self._load_state()
163
+ self._proxies: Dict[str, ProxyServer] = {} # multipass_name -> ProxyServer
164
+ # Note: _load_state is now async and will be called explicitly during provider setup
162
165
 
163
- def _load_state(self) -> None:
164
- """Load proxy state from file."""
166
+ async def _load_state(self) -> None:
167
+ """Load and restore proxy state from file."""
165
168
  try:
166
169
  state_path = Path(self.state_file)
167
170
  if state_path.exists():
168
171
  with open(state_path, 'r') as f:
169
172
  state = json.load(f)
170
- # We only need to restore port allocations
171
- # Actual proxy servers will be recreated as needed
172
- logger.info(f"Loaded proxy state for {len(state)} VMs")
173
+ # Restore proxy servers from saved state
174
+ restore_tasks = []
175
+ for requestor_name, proxy_info in state.items():
176
+ # Get current multipass name for the requestor's VM
177
+ multipass_name = await self.name_mapper.get_multipass_name(requestor_name)
178
+ if multipass_name:
179
+ # Create task to restore proxy
180
+ task = self.add_vm(
181
+ vm_id=multipass_name, # Use multipass name for internal tracking
182
+ vm_ip=proxy_info['target'],
183
+ port=proxy_info['port']
184
+ )
185
+ restore_tasks.append(task)
186
+ else:
187
+ logger.warning(f"No multipass name found for requestor VM {requestor_name}")
188
+
189
+ # Wait for all proxies to be restored
190
+ if restore_tasks:
191
+ results = await asyncio.gather(*restore_tasks, return_exceptions=True)
192
+ successful = sum(1 for r in results if r is True)
193
+ logger.info(f"Restored {successful}/{len(state)} proxy configurations")
173
194
  except Exception as e:
174
195
  logger.error(f"Failed to load proxy state: {e}")
175
196
 
176
- def _save_state(self) -> None:
177
- """Save current proxy state to file."""
197
+ async def _save_state(self) -> None:
198
+ """Save current proxy state to file using requestor names."""
178
199
  try:
179
- state = {
180
- vm_id: {
181
- 'port': proxy.listen_port,
182
- 'target': proxy.target_host
183
- }
184
- for vm_id, proxy in self._proxies.items()
185
- }
200
+ state = {}
201
+ for multipass_name, proxy in self._proxies.items():
202
+ requestor_name = await self.name_mapper.get_requestor_name(multipass_name)
203
+ if requestor_name:
204
+ state[requestor_name] = {
205
+ 'port': proxy.listen_port,
206
+ 'target': proxy.target_host
207
+ }
186
208
  os.makedirs(os.path.dirname(self.state_file), exist_ok=True)
187
209
  with open(self.state_file, 'w') as f:
188
210
  json.dump(state, f)
@@ -193,7 +215,7 @@ class PythonProxyManager:
193
215
  """Add proxy configuration for a new VM.
194
216
 
195
217
  Args:
196
- vm_id: Unique identifier for the VM
218
+ vm_id: Unique identifier for the VM (multipass name)
197
219
  vm_ip: IP address of the VM
198
220
  port: Optional specific port to use, if not provided one will be allocated
199
221
 
@@ -213,7 +235,7 @@ class PythonProxyManager:
213
235
  await proxy.start()
214
236
 
215
237
  self._proxies[vm_id] = proxy
216
- self._save_state()
238
+ await self._save_state()
217
239
 
218
240
  logger.info(f"Started proxy for VM {vm_id} on port {port}")
219
241
  return True
@@ -229,14 +251,14 @@ class PythonProxyManager:
229
251
  """Remove proxy configuration for a VM.
230
252
 
231
253
  Args:
232
- vm_id: Unique identifier for the VM
254
+ vm_id: Unique identifier for the VM (multipass name)
233
255
  """
234
256
  try:
235
257
  if vm_id in self._proxies:
236
258
  proxy = self._proxies.pop(vm_id)
237
259
  await proxy.stop()
238
260
  self.port_manager.deallocate_port(vm_id)
239
- self._save_state()
261
+ await self._save_state()
240
262
  logger.info(f"Removed proxy for VM {vm_id}")
241
263
  except Exception as e:
242
264
  logger.error(f"Failed to remove proxy for VM {vm_id}: {e}")
@@ -257,7 +279,7 @@ class PythonProxyManager:
257
279
  cleanup_errors.append(f"Failed to remove proxy for VM {vm_id}: {e}")
258
280
 
259
281
  try:
260
- self._save_state()
282
+ await self._save_state()
261
283
  except Exception as e:
262
284
  cleanup_errors.append(f"Failed to save state: {e}")
263
285
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "golem-vm-provider"
3
- version = "0.1.18"
3
+ version = "0.1.20"
4
4
  description = "VM on Golem Provider Node - Run your own provider node to offer VMs on the Golem Network"
5
5
  authors = ["Phillip Jensen <phillip+vm-on-golem@golemgrid.com>"]
6
6
  readme = "README.md"