golem-vm-provider 0.1.13__tar.gz → 0.1.14__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 (25) hide show
  1. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/PKG-INFO +1 -1
  2. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/config.py +60 -33
  3. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/main.py +4 -32
  4. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/pyproject.toml +1 -1
  5. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/README.md +0 -0
  6. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/__init__.py +0 -0
  7. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/api/__init__.py +0 -0
  8. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/api/models.py +0 -0
  9. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/api/routes.py +0 -0
  10. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/discovery/__init__.py +0 -0
  11. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/discovery/advertiser.py +0 -0
  12. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/discovery/resource_tracker.py +0 -0
  13. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/network/port_verifier.py +0 -0
  14. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/security/ethereum.py +0 -0
  15. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/ascii_art.py +0 -0
  16. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/logging.py +0 -0
  17. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/port_display.py +0 -0
  18. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/retry.py +0 -0
  19. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/__init__.py +0 -0
  20. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/cloud_init.py +0 -0
  21. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/models.py +0 -0
  22. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/multipass.py +0 -0
  23. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/name_mapper.py +0 -0
  24. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/port_manager.py +0 -0
  25. {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/proxy_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: golem-vm-provider
3
- Version: 0.1.13
3
+ Version: 0.1.14
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
@@ -59,22 +59,41 @@ class Settings(BaseSettings):
59
59
 
60
60
  @validator("VM_DATA_DIR", pre=True)
61
61
  def resolve_vm_data_dir(cls, v: str) -> str:
62
- """Resolve VM data directory path."""
62
+ """Resolve and create VM data directory path."""
63
63
  if not v:
64
- return str(Path.home() / ".golem" / "provider" / "vms")
65
- path = Path(v)
66
- if not path.is_absolute():
67
- path = Path.home() / path
64
+ path = Path.home() / ".golem" / "provider" / "vms"
65
+ else:
66
+ path = Path(v)
67
+ if not path.is_absolute():
68
+ path = Path.home() / path
69
+
70
+ try:
71
+ path.mkdir(parents=True, exist_ok=True)
72
+ logger.debug(f"Created VM data directory at {path}")
73
+ except Exception as e:
74
+ logger.error(f"Failed to create VM data directory at {path}: {e}")
75
+ raise ValueError(f"Failed to create VM data directory: {e}")
76
+
68
77
  return str(path)
69
78
 
70
79
  @validator("SSH_KEY_DIR", pre=True)
71
80
  def resolve_ssh_key_dir(cls, v: str) -> str:
72
- """Resolve SSH key directory path."""
81
+ """Resolve and create SSH key directory path with secure permissions."""
73
82
  if not v:
74
- return str(Path.home() / ".golem" / "provider" / "ssh")
75
- path = Path(v)
76
- if not path.is_absolute():
77
- path = Path.home() / path
83
+ path = Path.home() / ".golem" / "provider" / "ssh"
84
+ else:
85
+ path = Path(v)
86
+ if not path.is_absolute():
87
+ path = Path.home() / path
88
+
89
+ try:
90
+ path.mkdir(parents=True, exist_ok=True)
91
+ path.chmod(0o700) # Secure permissions for SSH keys
92
+ logger.debug(f"Created SSH key directory at {path} with secure permissions")
93
+ except Exception as e:
94
+ logger.error(f"Failed to create SSH key directory at {path}: {e}")
95
+ raise ValueError(f"Failed to create SSH key directory: {e}")
96
+
78
97
  return str(path)
79
98
 
80
99
  # Resource Settings
@@ -108,20 +127,22 @@ class Settings(BaseSettings):
108
127
 
109
128
  # If path provided via environment variable, ONLY validate that path
110
129
  if v:
111
- logger.debug(f"Using provided multipass path: {v}")
130
+ logger.info(f"Checking multipass binary at: {v}")
112
131
  if not validate_path(v):
113
- logger.error(f"Provided path {v} is invalid or not executable")
114
- raise ValueError(f"Invalid multipass binary path: {v}")
132
+ msg = f"Invalid multipass binary path: {v} (not found or not executable)"
133
+ logger.error(msg)
134
+ raise ValueError(msg)
135
+ logger.info(f"✓ Found valid multipass binary at: {v}")
115
136
  return v
116
137
 
117
- logger.debug("No multipass path provided, attempting auto-detection")
138
+ logger.info("No multipass path provided, attempting auto-detection...")
118
139
  system = platform.system().lower()
119
- logger.debug(f"Detected OS: {system}")
140
+ logger.info(f"Detected OS: {system}")
120
141
  binary_name = "multipass.exe" if system == "windows" else "multipass"
121
142
 
122
143
  # Try to find multipass based on OS
123
144
  if system == "linux":
124
- logger.debug("Checking for snap installation on Linux")
145
+ logger.info("Checking for snap installation...")
125
146
  # First try to find snap and check if multipass is installed
126
147
  try:
127
148
  # Check if snap exists
@@ -132,7 +153,7 @@ class Settings(BaseSettings):
132
153
  check=True
133
154
  )
134
155
  if snap_result.returncode == 0:
135
- logger.debug("Found snap, checking for multipass installation")
156
+ logger.info("Found snap, checking for multipass installation...")
136
157
  # Check if multipass is installed via snap
137
158
  try:
138
159
  snap_list = subprocess.run(
@@ -144,13 +165,13 @@ class Settings(BaseSettings):
144
165
  if snap_list.returncode == 0:
145
166
  snap_path = "/snap/bin/multipass"
146
167
  if validate_path(snap_path):
147
- logger.debug(f"Found multipass via snap at {snap_path}")
168
+ logger.info(f"Found multipass via snap at {snap_path}")
148
169
  return snap_path
149
170
  except subprocess.CalledProcessError:
150
- logger.debug("Multipass not installed via snap")
171
+ logger.info("Multipass not installed via snap")
151
172
  pass
152
173
  except subprocess.CalledProcessError:
153
- logger.debug("Snap not found")
174
+ logger.info("Snap not found")
154
175
  pass
155
176
 
156
177
  # Common Linux paths if snap installation not found
@@ -159,7 +180,7 @@ class Settings(BaseSettings):
159
180
  "/usr/bin",
160
181
  "/snap/bin"
161
182
  ]
162
- logger.debug(f"Checking common Linux paths: {search_paths}")
183
+ logger.info(f"Checking common Linux paths: {', '.join(search_paths)}")
163
184
 
164
185
  elif system == "darwin": # macOS
165
186
  search_paths = [
@@ -167,7 +188,7 @@ class Settings(BaseSettings):
167
188
  "/usr/local/bin", # Intel Mac
168
189
  "/opt/local/bin" # MacPorts
169
190
  ]
170
- logger.debug(f"Checking macOS paths: {search_paths}")
191
+ logger.info(f"Checking macOS paths: {', '.join(search_paths)}")
171
192
 
172
193
  elif system == "windows":
173
194
  search_paths = [
@@ -175,21 +196,18 @@ class Settings(BaseSettings):
175
196
  os.path.expandvars(r"%ProgramFiles(x86)%\Multipass"),
176
197
  os.path.expandvars(r"%LocalAppData%\Multipass")
177
198
  ]
178
- logger.debug(f"Checking Windows paths: {search_paths}")
199
+ logger.info(f"Checking Windows paths: {', '.join(search_paths)}")
179
200
 
180
201
  else:
181
202
  search_paths = ["/usr/local/bin", "/usr/bin"]
182
- logger.debug(f"Checking default paths: {search_paths}")
203
+ logger.info(f"Checking default paths: {', '.join(search_paths)}")
183
204
 
184
205
  # Search for multipass binary in OS-specific paths
185
206
  for directory in search_paths:
186
207
  path = os.path.join(directory, binary_name)
187
- logger.debug(f"Checking path: {path}")
188
208
  if validate_path(path):
189
- logger.debug(f"Found valid multipass binary at: {path}")
209
+ logger.info(f"Found valid multipass binary at: {path}")
190
210
  return path
191
- else:
192
- logger.debug(f"No valid multipass binary at: {path}")
193
211
 
194
212
  # OS-specific installation instructions
195
213
  if system == "linux":
@@ -224,12 +242,21 @@ class Settings(BaseSettings):
224
242
 
225
243
  @validator("PROXY_STATE_DIR", pre=True)
226
244
  def resolve_proxy_state_dir(cls, v: str) -> str:
227
- """Resolve proxy state directory path."""
245
+ """Resolve and create proxy state directory path."""
228
246
  if not v:
229
- return str(Path.home() / ".golem" / "provider" / "proxy")
230
- path = Path(v)
231
- if not path.is_absolute():
232
- path = Path.home() / path
247
+ path = Path.home() / ".golem" / "provider" / "proxy"
248
+ else:
249
+ path = Path(v)
250
+ if not path.is_absolute():
251
+ path = Path.home() / path
252
+
253
+ try:
254
+ path.mkdir(parents=True, exist_ok=True)
255
+ logger.debug(f"Created proxy state directory at {path}")
256
+ except Exception as e:
257
+ logger.error(f"Failed to create proxy state directory at {path}: {e}")
258
+ raise ValueError(f"Failed to create proxy state directory: {e}")
259
+
233
260
  return str(path)
234
261
 
235
262
  @validator("PUBLIC_IP", pre=True)
@@ -163,41 +163,13 @@ __all__ = ["app", "start"]
163
163
 
164
164
  def check_requirements():
165
165
  """Check if all requirements are met."""
166
- import os
167
- from pathlib import Path
168
-
169
- # Check if multipass is installed
170
- multipass_path = os.environ.get('GOLEM_PROVIDER_MULTIPASS_BINARY_PATH', '/usr/local/bin/multipass')
171
- if not Path(multipass_path).exists():
172
- logger.error(f"Multipass binary not found at {multipass_path}")
173
- return False
174
-
175
- # Check required directories
176
- vm_data_dir = os.environ.get(
177
- 'GOLEM_PROVIDER_VM_DATA_DIR',
178
- str(Path.home() / '.golem' / 'provider' / 'vms')
179
- )
180
- ssh_key_dir = os.environ.get(
181
- 'GOLEM_PROVIDER_SSH_KEY_DIR',
182
- str(Path.home() / '.golem' / 'provider' / 'ssh')
183
- )
184
- proxy_state_dir = os.environ.get(
185
- 'GOLEM_PROVIDER_PROXY_STATE_DIR',
186
- str(Path.home() / '.golem' / 'provider' / 'proxy')
187
- )
188
-
189
166
  try:
190
- # Create and secure directories
191
- for directory in [vm_data_dir, ssh_key_dir, proxy_state_dir]:
192
- path = Path(directory)
193
- path.mkdir(parents=True, exist_ok=True)
194
- if directory == ssh_key_dir:
195
- path.chmod(0o700) # Secure permissions for SSH keys
167
+ # Import settings to trigger validation
168
+ from .config import settings
169
+ return True
196
170
  except Exception as e:
197
- logger.error(f"Failed to create required directories: {e}")
171
+ logger.error(f"Requirements check failed: {e}")
198
172
  return False
199
-
200
- return True
201
173
 
202
174
  async def verify_provider_port(port: int) -> bool:
203
175
  """Verify that the provider port is available for binding.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "golem-vm-provider"
3
- version = "0.1.13"
3
+ version = "0.1.14"
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"