cloudx-proxy 0.3.8__tar.gz → 0.3.10__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 (22) hide show
  1. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/CHANGELOG.md +14 -0
  2. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/PKG-INFO +1 -1
  3. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy/_version.py +2 -2
  4. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy/setup.py +55 -160
  5. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy.egg-info/PKG-INFO +1 -1
  6. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/.github/workflows/release.yml +0 -0
  7. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/.gitignore +0 -0
  8. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/.releaserc +0 -0
  9. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/CONTRIBUTING.md +0 -0
  10. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/LICENSE +0 -0
  11. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/README.md +0 -0
  12. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy/__init__.py +0 -0
  13. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy/cli.py +0 -0
  14. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy/core.py +0 -0
  15. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy.egg-info/SOURCES.txt +0 -0
  16. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy.egg-info/dependency_links.txt +0 -0
  17. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy.egg-info/entry_points.txt +0 -0
  18. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy.egg-info/requires.txt +0 -0
  19. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/cloudx_proxy.egg-info/top_level.txt +0 -0
  20. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/package.json +0 -0
  21. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/pyproject.toml +0 -0
  22. {cloudx_proxy-0.3.8 → cloudx_proxy-0.3.10}/setup.cfg +0 -0
@@ -1,3 +1,17 @@
1
+ ## [0.3.10](https://github.com/easytocloud/cloudX-proxy/compare/v0.3.9...v0.3.10) (2025-02-11)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * remove AWS api calls in favour of ssh ([c3430ea](https://github.com/easytocloud/cloudX-proxy/commit/c3430ea0146c8b814f453dda8db5a5a5db975e09))
7
+
8
+ ## [0.3.9](https://github.com/easytocloud/cloudX-proxy/compare/v0.3.8...v0.3.9) (2025-02-11)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * use ssm for ec2 operations ([e227818](https://github.com/easytocloud/cloudX-proxy/commit/e2278184b443c4051aa355745985543757d980a3))
14
+
1
15
  ## [0.3.8](https://github.com/easytocloud/cloudX-proxy/compare/v0.3.7...v0.3.8) (2025-02-11)
2
16
 
3
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudx-proxy
3
- Version: 0.3.8
3
+ Version: 0.3.10
4
4
  Summary: SSH proxy command to connect VSCode with Cloud9/CloudX instance using AWS Systems Manager
5
5
  Author-email: easytocloud <info@easytocloud.com>
6
6
  License: MIT License
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.3.8'
16
- __version_tuple__ = version_tuple = (0, 3, 8)
15
+ __version__ = version = '0.3.10'
16
+ __version_tuple__ = version_tuple = (0, 3, 10)
@@ -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) -> Tuple[bool, bool, bool]:
361
- """Check if instance setup is complete.
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
- Tuple[bool, bool, bool]: (ssm_accessible, is_running, is_setup_complete)
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
- session = boto3.Session(profile_name=self.profile)
371
- ssm = session.client('ssm')
372
- ec2 = session.client('ec2')
373
-
374
- # First check if instance exists and its power state
375
- try:
376
- # Use the provided profile for EC2 operations
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
- # Now check SSM connectivity
393
- try:
394
- self.print_status("Checking SSM connectivity...", None, 4)
395
- response = ssm.describe_instance_information(
396
- Filters=[{'Key': 'InstanceIds', 'Values': [instance_id]}]
397
- )
398
- if not response['InstanceInformationList']:
399
- self.print_status("Instance is running but not yet accessible via SSM", False, 4)
400
- self.print_status("This is normal if the instance is still configuring", None, 4)
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
- status = result['StandardOutputContent'].strip()
437
- self.print_status(f"Setup status: {status}", None, 4)
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
- except Exception as e:
442
- self.print_status(f"Error checking SSM status: {e}", False, 4)
443
- return False, True, False
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"\033[1;91mError:\033[0m {str(e)}", False, 4)
447
- return False, False, 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 setup to complete.
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 setup completed successfully or user chose to continue
413
+ bool: True if instance is accessible or user chose to continue
457
414
  """
458
- self.print_header("Instance Setup Check")
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 not ssm_accessible and not is_running:
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
- if not ssm_accessible:
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
- self.print_status("Skipping instance setup check", None, 2)
519
- return True
422
+ return False
520
423
 
521
- self.print_status("Waiting for setup to complete...", None, 2)
424
+ self.print_status("Waiting for SSH access...", None, 2)
522
425
  dots = 0
523
- while True:
524
- ssm_accessible, is_running, is_complete = self.check_instance_setup(instance_id)
525
-
526
- if not is_running:
527
- self.print_status("Instance is no longer running", False, 2)
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudx-proxy
3
- Version: 0.3.8
3
+ Version: 0.3.10
4
4
  Summary: SSH proxy command to connect VSCode with Cloud9/CloudX instance using AWS Systems Manager
5
5
  Author-email: easytocloud <info@easytocloud.com>
6
6
  License: MIT License
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes