cloudx-proxy 0.3.9__py3-none-any.whl → 0.3.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.
- cloudx_proxy/_version.py +2 -2
- cloudx_proxy/setup.py +55 -134
- {cloudx_proxy-0.3.9.dist-info → cloudx_proxy-0.3.10.dist-info}/METADATA +1 -1
- cloudx_proxy-0.3.10.dist-info/RECORD +11 -0
- cloudx_proxy-0.3.9.dist-info/RECORD +0 -11
- {cloudx_proxy-0.3.9.dist-info → cloudx_proxy-0.3.10.dist-info}/LICENSE +0 -0
- {cloudx_proxy-0.3.9.dist-info → cloudx_proxy-0.3.10.dist-info}/WHEEL +0 -0
- {cloudx_proxy-0.3.9.dist-info → cloudx_proxy-0.3.10.dist-info}/entry_points.txt +0 -0
- {cloudx_proxy-0.3.9.dist-info → cloudx_proxy-0.3.10.dist-info}/top_level.txt +0 -0
cloudx_proxy/_version.py
CHANGED
cloudx_proxy/setup.py
CHANGED
@@ -357,166 +357,87 @@ Host cloudx-{cloudx_env}-{hostname}
|
|
357
357
|
return True
|
358
358
|
return False
|
359
359
|
|
360
|
-
def check_instance_setup(self, instance_id: str
|
361
|
-
"""Check if instance
|
360
|
+
def check_instance_setup(self, instance_id: str, hostname: str, cloudx_env: str) -> bool:
|
361
|
+
"""Check if instance is accessible via SSH.
|
362
362
|
|
363
363
|
Args:
|
364
364
|
instance_id: EC2 instance ID
|
365
|
+
hostname: Hostname for the instance
|
366
|
+
cloudx_env: CloudX environment
|
365
367
|
|
366
368
|
Returns:
|
367
|
-
|
369
|
+
bool: True if instance is accessible
|
368
370
|
"""
|
371
|
+
ssh_host = f"cloudx-{cloudx_env}-{hostname}"
|
372
|
+
self.print_status(f"Checking SSH connection to {ssh_host}...", None, 4)
|
373
|
+
|
369
374
|
try:
|
370
|
-
|
371
|
-
|
372
|
-
|
375
|
+
# Try to connect with a simple command that will exit immediately
|
376
|
+
result = subprocess.run(
|
377
|
+
['ssh', ssh_host, 'exit'],
|
378
|
+
capture_output=True,
|
379
|
+
text=True,
|
380
|
+
timeout=10 # 10 second timeout
|
381
|
+
)
|
373
382
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
self.print_status("Instance
|
383
|
-
self.print_status("This could mean the instance is stopped or still configuring", None, 4)
|
384
|
-
return True, False, False
|
385
|
-
|
386
|
-
# Check instance status from SSM
|
387
|
-
instance = instance_info[0]
|
388
|
-
ping_status = instance.get('PingStatus', '')
|
389
|
-
if ping_status != 'Online':
|
390
|
-
self.print_status(f"Instance SSM status: {ping_status}", False, 4)
|
391
|
-
return True, False, False
|
392
|
-
|
393
|
-
self.print_status("Instance is running and SSM connection established", True, 4)
|
394
|
-
|
395
|
-
# Check setup status using SSM command
|
396
|
-
self.print_status("Checking setup status...", None, 4)
|
397
|
-
response = ssm.send_command(
|
398
|
-
InstanceIds=[instance_id],
|
399
|
-
DocumentName='AWS-RunShellScript',
|
400
|
-
Parameters={
|
401
|
-
'commands': [
|
402
|
-
'test -f /home/ec2-user/.install-done && echo "DONE" || '
|
403
|
-
'test -f /home/ec2-user/.install-running && echo "RUNNING" || '
|
404
|
-
'echo "NOT_STARTED"'
|
405
|
-
]
|
406
|
-
}
|
407
|
-
)
|
408
|
-
|
409
|
-
command_id = response['Command']['CommandId']
|
410
|
-
|
411
|
-
# Wait for command completion
|
412
|
-
for _ in range(10): # 10 second timeout
|
413
|
-
time.sleep(1)
|
414
|
-
result = ssm.get_command_invocation(
|
415
|
-
CommandId=command_id,
|
416
|
-
InstanceId=instance_id
|
417
|
-
)
|
418
|
-
if result['Status'] in ['Success', 'Failed']:
|
419
|
-
break
|
420
|
-
|
421
|
-
is_setup_complete = result['Status'] == 'Success' and result['StandardOutputContent'].strip() == 'DONE'
|
422
|
-
|
423
|
-
if is_setup_complete:
|
424
|
-
self.print_status("Setup is complete", True, 4)
|
383
|
+
if result.returncode == 0:
|
384
|
+
self.print_status("SSH connection successful", True, 4)
|
385
|
+
return True
|
386
|
+
else:
|
387
|
+
self.print_status("SSH connection failed", False, 4)
|
388
|
+
if "Connection refused" in result.stderr:
|
389
|
+
self.print_status("Instance appears to be starting up. Please try again in a few minutes.", None, 4)
|
390
|
+
elif "Connection timed out" in result.stderr:
|
391
|
+
self.print_status("Instance may be stopped. Please start it through the appropriate channels.", None, 4)
|
425
392
|
else:
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
return True, True, is_setup_complete
|
393
|
+
self.print_status(f"Error: {result.stderr.strip()}", None, 4)
|
394
|
+
return False
|
430
395
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
396
|
+
except subprocess.TimeoutExpired:
|
397
|
+
self.print_status("SSH connection timed out", False, 4)
|
398
|
+
self.print_status("Instance may be stopped or still starting up", None, 4)
|
399
|
+
return False
|
435
400
|
except Exception as e:
|
436
|
-
self.print_status(f"
|
437
|
-
return False
|
401
|
+
self.print_status(f"Error checking SSH connection: {str(e)}", False, 4)
|
402
|
+
return False
|
438
403
|
|
439
|
-
def wait_for_setup_completion(self, instance_id: str) -> bool:
|
440
|
-
"""Wait for instance
|
404
|
+
def wait_for_setup_completion(self, instance_id: str, hostname: str, cloudx_env: str) -> bool:
|
405
|
+
"""Wait for instance to become accessible via SSH.
|
441
406
|
|
442
407
|
Args:
|
443
408
|
instance_id: EC2 instance ID
|
409
|
+
hostname: Hostname for the instance
|
410
|
+
cloudx_env: CloudX environment
|
444
411
|
|
445
412
|
Returns:
|
446
|
-
bool: True if
|
413
|
+
bool: True if instance is accessible or user chose to continue
|
447
414
|
"""
|
448
|
-
self.print_header("Instance
|
449
|
-
self.print_status(f"Checking instance {instance_id} status...")
|
415
|
+
self.print_header("Instance Access Check")
|
450
416
|
|
451
|
-
|
452
|
-
|
453
|
-
if not ssm_accessible and not is_running:
|
454
|
-
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
455
|
-
if continue_setup:
|
456
|
-
self.print_status("Continuing setup despite instance access issues", None, 2)
|
457
|
-
return True
|
458
|
-
return False
|
459
|
-
|
460
|
-
if not is_running:
|
461
|
-
start_instance = self.prompt("Would you like to start the instance?", "Y").lower() != 'n'
|
462
|
-
if not start_instance:
|
463
|
-
return False
|
464
|
-
|
465
|
-
self.print_status("Cannot directly start the instance. Please start it through the appropriate channels.", False, 2)
|
466
|
-
self.print_status("Once started, run this command again to configure SSH access.", None, 2)
|
467
|
-
return False
|
468
|
-
|
469
|
-
if is_complete:
|
470
|
-
self.print_status("Instance setup is complete", True, 2)
|
417
|
+
if self.check_instance_setup(instance_id, hostname, cloudx_env):
|
471
418
|
return True
|
472
|
-
|
473
|
-
if not ssm_accessible:
|
474
|
-
self.print_status("Waiting for SSM access...", None, 2)
|
475
|
-
# Wait for SSM access
|
476
|
-
for _ in range(30): # 5 minute timeout
|
477
|
-
time.sleep(10)
|
478
|
-
ssm_accessible, is_running, is_complete = self.check_instance_setup(instance_id)
|
479
|
-
if ssm_accessible or not is_running:
|
480
|
-
break
|
481
419
|
|
482
|
-
|
483
|
-
self.print_status("Timeout waiting for SSM access", False, 2)
|
484
|
-
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
485
|
-
if continue_setup:
|
486
|
-
self.print_status("Continuing setup despite SSM access issues", None, 2)
|
487
|
-
return True
|
488
|
-
return False
|
489
|
-
|
490
|
-
wait = self.prompt("Instance setup is not complete. Would you like to wait?", "Y").lower() != 'n'
|
420
|
+
wait = self.prompt("Would you like to wait for the instance to become accessible?", "Y").lower() != 'n'
|
491
421
|
if not wait:
|
492
|
-
|
493
|
-
return True
|
422
|
+
return False
|
494
423
|
|
495
|
-
self.print_status("Waiting for
|
424
|
+
self.print_status("Waiting for SSH access...", None, 2)
|
496
425
|
dots = 0
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
503
|
-
if continue_setup:
|
504
|
-
self.print_status("Continuing setup despite instance issues", None, 2)
|
505
|
-
return True
|
506
|
-
return False
|
507
|
-
|
508
|
-
if not ssm_accessible:
|
509
|
-
self.print_status("Lost SSM access to instance", False, 2)
|
510
|
-
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
511
|
-
if continue_setup:
|
512
|
-
self.print_status("Continuing setup despite SSM access issues", None, 2)
|
513
|
-
return True
|
514
|
-
return False
|
515
|
-
|
516
|
-
if is_complete:
|
517
|
-
self.print_status("Instance setup completed successfully", True, 2)
|
426
|
+
attempts = 0
|
427
|
+
max_attempts = 30 # 5 minute timeout (10 seconds * 30)
|
428
|
+
|
429
|
+
while attempts < max_attempts:
|
430
|
+
if self.check_instance_setup(instance_id, hostname, cloudx_env):
|
518
431
|
return True
|
519
432
|
|
520
433
|
dots = (dots + 1) % 4
|
521
434
|
print(f"\r {'.' * dots}{' ' * (3 - dots)}", end='', flush=True)
|
522
435
|
time.sleep(10)
|
436
|
+
attempts += 1
|
437
|
+
|
438
|
+
self.print_status("Timeout waiting for SSH access", False, 2)
|
439
|
+
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
440
|
+
if continue_setup:
|
441
|
+
self.print_status("Continuing setup despite SSH access issues", None, 2)
|
442
|
+
return True
|
443
|
+
return False
|
@@ -0,0 +1,11 @@
|
|
1
|
+
cloudx_proxy/__init__.py,sha256=ZZ2O_m9OFJm18AxMSuYJt4UjSuSqyJlYRaZMoets498,61
|
2
|
+
cloudx_proxy/_version.py,sha256=QTWoiVZ8kBQVv_3SZGJVwOxMqBDiTg3_qUjTLFx1eco,413
|
3
|
+
cloudx_proxy/cli.py,sha256=Ph-m8lDsdU2zZab9Y6YgBBzd_UDouBnfNrYFFx0bI_E,3426
|
4
|
+
cloudx_proxy/core.py,sha256=WjKoqMmmnt6e_4JMeq4gTka75JAvQcMUs9r9XUBLmFE,7289
|
5
|
+
cloudx_proxy/setup.py,sha256=GNgZcUnnJG7q7npUl4QW_4mWfJT0gKZ_i1fwmxj3pmI,18672
|
6
|
+
cloudx_proxy-0.3.10.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
|
7
|
+
cloudx_proxy-0.3.10.dist-info/METADATA,sha256=K2MpuinViH09VSedgNCF44liXMJoy8c6-Gc3WD8rhSg,14038
|
8
|
+
cloudx_proxy-0.3.10.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
9
|
+
cloudx_proxy-0.3.10.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
|
10
|
+
cloudx_proxy-0.3.10.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
|
11
|
+
cloudx_proxy-0.3.10.dist-info/RECORD,,
|
@@ -1,11 +0,0 @@
|
|
1
|
-
cloudx_proxy/__init__.py,sha256=ZZ2O_m9OFJm18AxMSuYJt4UjSuSqyJlYRaZMoets498,61
|
2
|
-
cloudx_proxy/_version.py,sha256=nV2HEiFwTdaOZoFEyVxxG_D8Oq_nlSmX2vHL4jK4h6w,411
|
3
|
-
cloudx_proxy/cli.py,sha256=Ph-m8lDsdU2zZab9Y6YgBBzd_UDouBnfNrYFFx0bI_E,3426
|
4
|
-
cloudx_proxy/core.py,sha256=WjKoqMmmnt6e_4JMeq4gTka75JAvQcMUs9r9XUBLmFE,7289
|
5
|
-
cloudx_proxy/setup.py,sha256=dj8YQgCI03J03inv_b8dDhch8KHcI3hYQWYQqpr9azs,22540
|
6
|
-
cloudx_proxy-0.3.9.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
|
7
|
-
cloudx_proxy-0.3.9.dist-info/METADATA,sha256=S7tYMFC9-izIgqTYOKrpJyde9VNmMojdopz9TaAh30c,14037
|
8
|
-
cloudx_proxy-0.3.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
9
|
-
cloudx_proxy-0.3.9.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
|
10
|
-
cloudx_proxy-0.3.9.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
|
11
|
-
cloudx_proxy-0.3.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|