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.
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/PKG-INFO +1 -1
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/config.py +60 -33
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/main.py +4 -32
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/pyproject.toml +1 -1
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/README.md +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/__init__.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/api/__init__.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/api/models.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/api/routes.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/discovery/__init__.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/discovery/advertiser.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/discovery/resource_tracker.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/network/port_verifier.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/security/ethereum.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/ascii_art.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/logging.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/port_display.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/utils/retry.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/__init__.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/cloud_init.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/models.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/multipass.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/name_mapper.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/port_manager.py +0 -0
- {golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/vm/proxy_manager.py +0 -0
@@ -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
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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.
|
130
|
+
logger.info(f"Checking multipass binary at: {v}")
|
112
131
|
if not validate_path(v):
|
113
|
-
|
114
|
-
|
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.
|
138
|
+
logger.info("No multipass path provided, attempting auto-detection...")
|
118
139
|
system = platform.system().lower()
|
119
|
-
logger.
|
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.
|
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.
|
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.
|
168
|
+
logger.info(f"✓ Found multipass via snap at {snap_path}")
|
148
169
|
return snap_path
|
149
170
|
except subprocess.CalledProcessError:
|
150
|
-
logger.
|
171
|
+
logger.info("✗ Multipass not installed via snap")
|
151
172
|
pass
|
152
173
|
except subprocess.CalledProcessError:
|
153
|
-
logger.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
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
|
-
#
|
191
|
-
|
192
|
-
|
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"
|
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.
|
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"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{golem_vm_provider-0.1.13 → golem_vm_provider-0.1.14}/provider/discovery/resource_tracker.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|