cloudx-proxy 0.3.8__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 -160
- {cloudx_proxy-0.3.8.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.8.dist-info/RECORD +0 -11
- {cloudx_proxy-0.3.8.dist-info → cloudx_proxy-0.3.10.dist-info}/LICENSE +0 -0
- {cloudx_proxy-0.3.8.dist-info → cloudx_proxy-0.3.10.dist-info}/WHEEL +0 -0
- {cloudx_proxy-0.3.8.dist-info → cloudx_proxy-0.3.10.dist-info}/entry_points.txt +0 -0
- {cloudx_proxy-0.3.8.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,192 +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
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
response = session.client('ec2').describe_instances(InstanceIds=[instance_id])
|
378
|
-
if not response['Reservations']:
|
379
|
-
self.print_status("Instance not found", False, 4)
|
380
|
-
return False, False, False
|
381
|
-
|
382
|
-
instance = response['Reservations'][0]['Instances'][0]
|
383
|
-
state = instance['State']['Name']
|
384
|
-
|
385
|
-
if state != 'running':
|
386
|
-
self.print_status(f"Instance is {state}", False, 4)
|
387
|
-
return True, False, False
|
388
|
-
except Exception as e:
|
389
|
-
self.print_status(f"Error checking instance state: {e}", False, 4)
|
390
|
-
return False, False, False
|
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
|
+
)
|
391
382
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
self.print_status("
|
401
|
-
return True, True, False
|
402
|
-
|
403
|
-
self.print_status("SSM connection established", True, 4)
|
404
|
-
|
405
|
-
# Check setup status using SSM command
|
406
|
-
self.print_status("Checking setup status...", None, 4)
|
407
|
-
response = ssm.send_command(
|
408
|
-
InstanceIds=[instance_id],
|
409
|
-
DocumentName='AWS-RunShellScript',
|
410
|
-
Parameters={
|
411
|
-
'commands': [
|
412
|
-
'test -f /home/ec2-user/.install-done && echo "DONE" || '
|
413
|
-
'test -f /home/ec2-user/.install-running && echo "RUNNING" || '
|
414
|
-
'echo "NOT_STARTED"'
|
415
|
-
]
|
416
|
-
}
|
417
|
-
)
|
418
|
-
|
419
|
-
command_id = response['Command']['CommandId']
|
420
|
-
|
421
|
-
# Wait for command completion
|
422
|
-
for _ in range(10): # 10 second timeout
|
423
|
-
time.sleep(1)
|
424
|
-
result = ssm.get_command_invocation(
|
425
|
-
CommandId=command_id,
|
426
|
-
InstanceId=instance_id
|
427
|
-
)
|
428
|
-
if result['Status'] in ['Success', 'Failed']:
|
429
|
-
break
|
430
|
-
|
431
|
-
is_setup_complete = result['Status'] == 'Success' and result['StandardOutputContent'].strip() == 'DONE'
|
432
|
-
|
433
|
-
if is_setup_complete:
|
434
|
-
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)
|
435
392
|
else:
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
return True, True, is_setup_complete
|
393
|
+
self.print_status(f"Error: {result.stderr.strip()}", None, 4)
|
394
|
+
return False
|
440
395
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
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
|
445
400
|
except Exception as e:
|
446
|
-
self.print_status(f"
|
447
|
-
return False
|
401
|
+
self.print_status(f"Error checking SSH connection: {str(e)}", False, 4)
|
402
|
+
return False
|
448
403
|
|
449
|
-
def wait_for_setup_completion(self, instance_id: str) -> bool:
|
450
|
-
"""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.
|
451
406
|
|
452
407
|
Args:
|
453
408
|
instance_id: EC2 instance ID
|
409
|
+
hostname: Hostname for the instance
|
410
|
+
cloudx_env: CloudX environment
|
454
411
|
|
455
412
|
Returns:
|
456
|
-
bool: True if
|
413
|
+
bool: True if instance is accessible or user chose to continue
|
457
414
|
"""
|
458
|
-
self.print_header("Instance
|
459
|
-
self.print_status(f"Checking instance {instance_id} status...")
|
460
|
-
|
461
|
-
ssm_accessible, is_running, is_complete = self.check_instance_setup(instance_id)
|
415
|
+
self.print_header("Instance Access Check")
|
462
416
|
|
463
|
-
if
|
464
|
-
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
465
|
-
if continue_setup:
|
466
|
-
self.print_status("Continuing setup despite instance access issues", None, 2)
|
467
|
-
return True
|
468
|
-
return False
|
469
|
-
|
470
|
-
if not is_running:
|
471
|
-
start_instance = self.prompt("Would you like to start the instance?", "Y").lower() != 'n'
|
472
|
-
if not start_instance:
|
473
|
-
return False
|
474
|
-
|
475
|
-
try:
|
476
|
-
# Use the provided profile for EC2 operations
|
477
|
-
session = boto3.Session(profile_name=self.profile)
|
478
|
-
session.client('ec2').start_instances(InstanceIds=[instance_id])
|
479
|
-
self.print_status("Instance start requested. This may take a few minutes...", None, 2)
|
480
|
-
|
481
|
-
# Wait for instance to start
|
482
|
-
for _ in range(30): # 5 minute timeout
|
483
|
-
time.sleep(10)
|
484
|
-
ssm_accessible, is_running, is_complete = self.check_instance_setup(instance_id)
|
485
|
-
if is_running:
|
486
|
-
break
|
487
|
-
|
488
|
-
if not is_running:
|
489
|
-
self.print_status("Timeout waiting for instance to start", False, 2)
|
490
|
-
return False
|
491
|
-
except Exception as e:
|
492
|
-
self.print_status(f"Error starting instance: {e}", False, 2)
|
493
|
-
return False
|
494
|
-
|
495
|
-
if is_complete:
|
496
|
-
self.print_status("Instance setup is complete", True, 2)
|
417
|
+
if self.check_instance_setup(instance_id, hostname, cloudx_env):
|
497
418
|
return True
|
498
|
-
|
499
|
-
if not ssm_accessible:
|
500
|
-
self.print_status("Waiting for SSM access...", None, 2)
|
501
|
-
# Wait for SSM access
|
502
|
-
for _ in range(30): # 5 minute timeout
|
503
|
-
time.sleep(10)
|
504
|
-
ssm_accessible, is_running, is_complete = self.check_instance_setup(instance_id)
|
505
|
-
if ssm_accessible or not is_running:
|
506
|
-
break
|
507
419
|
|
508
|
-
|
509
|
-
self.print_status("Timeout waiting for SSM access", 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
|
-
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'
|
517
421
|
if not wait:
|
518
|
-
|
519
|
-
return True
|
422
|
+
return False
|
520
423
|
|
521
|
-
self.print_status("Waiting for
|
424
|
+
self.print_status("Waiting for SSH access...", None, 2)
|
522
425
|
dots = 0
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
529
|
-
if continue_setup:
|
530
|
-
self.print_status("Continuing setup despite instance issues", None, 2)
|
531
|
-
return True
|
532
|
-
return False
|
533
|
-
|
534
|
-
if not ssm_accessible:
|
535
|
-
self.print_status("Lost SSM access to instance", False, 2)
|
536
|
-
continue_setup = self.prompt("Would you like to continue anyway?", "Y").lower() != 'n'
|
537
|
-
if continue_setup:
|
538
|
-
self.print_status("Continuing setup despite SSM access issues", None, 2)
|
539
|
-
return True
|
540
|
-
return False
|
541
|
-
|
542
|
-
if is_complete:
|
543
|
-
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):
|
544
431
|
return True
|
545
432
|
|
546
433
|
dots = (dots + 1) % 4
|
547
434
|
print(f"\r {'.' * dots}{' ' * (3 - dots)}", end='', flush=True)
|
548
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=FAr0t5Ub_Olk5Ke3Xi4Oeu5jcLPAvKpdk9naAtMuou8,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=96FbRtGKHYa-V26wTP0m-JtkAFhGULgnCOO0PStB8ds,23725
|
6
|
-
cloudx_proxy-0.3.8.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
|
7
|
-
cloudx_proxy-0.3.8.dist-info/METADATA,sha256=EdfWsWYRH1GvR6scuD3HZTEqnMk3ljD_VCOaL4YNkx8,14037
|
8
|
-
cloudx_proxy-0.3.8.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
9
|
-
cloudx_proxy-0.3.8.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
|
10
|
-
cloudx_proxy-0.3.8.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
|
11
|
-
cloudx_proxy-0.3.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|