aetherscale

[unmaintained] code for a cloud provider tutorial
Log | Files | Refs | README | LICENSE

rabbitmq_vm_hosting.py (2406B)


      1 #!/usr/bin/env python
      2 
      3 import sys
      4 import time
      5 from typing import List
      6 
      7 from aetherscale.client import ServerCommunication
      8 
      9 
     10 def create_rabbitmq_vm(comm: ServerCommunication) -> str:
     11     responses = comm.send_msg({
     12         'command': 'create-vm',
     13         'options': {
     14             # The rabbitmq image has to be created before running this script
     15             'image': 'rabbitmq',
     16         }
     17     }, response_expected=True)
     18 
     19     if len(responses) != 1:
     20         raise RuntimeError(
     21             'Did not receive exactly one response, something went wrong')
     22 
     23     if responses[0]['execution-info']['status'] != 'success':
     24         raise RuntimeError('Execution was not successful')
     25 
     26     return responses[0]['response']['vm-id']
     27 
     28 
     29 def get_vm_ips(vm_id: str, comm: ServerCommunication) -> List[str]:
     30     responses = comm.send_msg({
     31         'command': 'list-vms',
     32     }, response_expected=True)
     33 
     34     for r in responses:
     35         try:
     36             for vm in r['response']:
     37                 if vm['vm-id'] == vm_id:
     38                     return vm['ip-addresses']
     39         except KeyError:
     40             pass
     41 
     42     return []
     43 
     44 
     45 def is_external_ip(ip: str) -> bool:
     46     """Quick hack to check whether an IP returned by list-vms is an
     47     external IP address"""
     48     if ':' in ip:
     49         first_part = ip.split(':')[0]
     50 
     51         try:
     52             if int('fe80', 16) <= int(first_part, 16) <= int('febf', 16):
     53                 # link-local
     54                 return False
     55         except ValueError:
     56             # if it cannot be parsed as hex, it's not in range
     57             return False
     58 
     59     if ip == '::1' or ip == '127.0.0.1':
     60         # localhost
     61         return False
     62 
     63     return True
     64 
     65 
     66 def format_ip_for_url(ip: str) -> str:
     67     if ':' in ip:
     68         return f'[{ip}]'
     69     else:
     70         return ip
     71 
     72 
     73 def main():
     74     with ServerCommunication() as comm:
     75         try:
     76             vm_id = create_rabbitmq_vm(comm)
     77         except RuntimeError as e:
     78             print(str(e), file=sys.stderr)
     79             sys.exit(1)
     80 
     81     time.sleep(30)
     82     # TODO: There seems to be a bug in ServerCommunication so that we can only
     83     # exchange one message pair per context
     84     # Probably related to the AMQ reply-to channel
     85     with ServerCommunication() as comm:
     86         ips = get_vm_ips(vm_id, comm)
     87 
     88     ips = [f'http://{format_ip_for_url(ip)}:15672/' for ip in ips
     89            if is_external_ip(ip)]
     90 
     91     print(ips)
     92 
     93 
     94 if __name__ == '__main__':
     95     main()