xenfra 0.1.8__tar.gz → 0.1.9__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 (24) hide show
  1. {xenfra-0.1.8 → xenfra-0.1.9}/PKG-INFO +1 -1
  2. {xenfra-0.1.8 → xenfra-0.1.9}/pyproject.toml +1 -1
  3. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/engine.py +33 -4
  4. {xenfra-0.1.8 → xenfra-0.1.9}/README.md +0 -0
  5. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/__init__.py +0 -0
  6. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/api/auth.py +0 -0
  7. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/api/billing.py +0 -0
  8. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/api/connections.py +0 -0
  9. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/api/main.py +0 -0
  10. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/api/webhooks.py +0 -0
  11. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/cli/main.py +0 -0
  12. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/config.py +0 -0
  13. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/db/models.py +0 -0
  14. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/db/session.py +0 -0
  15. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/dependencies.py +0 -0
  16. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/dockerizer.py +0 -0
  17. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/mcp_client.py +0 -0
  18. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/models.py +0 -0
  19. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/recipes.py +0 -0
  20. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/security.py +0 -0
  21. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/templates/Dockerfile.j2 +0 -0
  22. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/templates/cloud-init.sh.j2 +0 -0
  23. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/templates/docker-compose.yml.j2 +0 -0
  24. {xenfra-0.1.8 → xenfra-0.1.9}/src/xenfra/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: xenfra
3
- Version: 0.1.8
3
+ Version: 0.1.9
4
4
  Summary: A 'Zen Mode' infrastructure engine for Python developers.
5
5
  Author: xenfra-cloud
6
6
  Author-email: xenfra-cloud <xenfracloud@gmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xenfra"
3
- version = "0.1.8"
3
+ version = "0.1.9"
4
4
  description = "A 'Zen Mode' infrastructure engine for Python developers."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -44,7 +44,15 @@ class InfraEngine:
44
44
 
45
45
  def _get_connection(self, ip_address: str):
46
46
  """Establishes a Fabric connection to the server."""
47
- return fabric.Connection(host=ip_address, user="root", connect_kwargs={"password": None}) # Assumes SSH key auth
47
+ private_key_path = str(Path.home() / ".ssh" / "id_rsa")
48
+ if not Path(private_key_path).exists():
49
+ raise DeploymentError("No private SSH key found at ~/.ssh/id_rsa.", stage="Setup")
50
+
51
+ return fabric.Connection(
52
+ host=ip_address,
53
+ user="root",
54
+ connect_kwargs={"key_filename": [private_key_path]},
55
+ )
48
56
 
49
57
  def get_user_info(self):
50
58
  """Retrieves user account information."""
@@ -189,12 +197,33 @@ class InfraEngine:
189
197
  while True:
190
198
  droplet.load()
191
199
  if droplet.status == 'active':
192
- logger(" - Droplet is active. Waiting for cloud-init to complete...")
200
+ logger(" - Droplet is active. Waiting for SSH to be available...")
193
201
  break
194
202
  time.sleep(10)
195
-
203
+
196
204
  ip_address = droplet.ip_address
197
- with self._get_connection(ip_address) as conn:
205
+
206
+ # Retry SSH connection
207
+ conn = None
208
+ max_retries = 12 # 2-minute timeout for SSH
209
+ for i in range(max_retries):
210
+ try:
211
+ logger(f" - Attempting SSH connection ({i+1}/{max_retries})...")
212
+ conn = self._get_connection(ip_address)
213
+ conn.open() # Explicitly open the connection
214
+ logger(" - SSH connection established.")
215
+ break
216
+ except Exception as e:
217
+ if i < max_retries - 1:
218
+ logger(f" - SSH connection failed. Retrying in 10s...")
219
+ time.sleep(10)
220
+ else:
221
+ raise DeploymentError(f"Failed to establish SSH connection: {e}", stage="Polling")
222
+
223
+ if not conn or not conn.is_connected:
224
+ raise DeploymentError("Could not establish SSH connection.", stage="Polling")
225
+
226
+ with conn:
198
227
  for i in range(30): # 5-minute timeout for cloud-init
199
228
  if conn.run("test -f /root/setup_complete", warn=True).ok:
200
229
  logger(" - Cloud-init setup complete.")
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
File without changes