diff --git a/scripts/floatup.py b/scripts/floatup.py index 5647d7dc306e28791a4f8fb2e4536d6000b68ad3..fa3aa850d2121401a6a99d07eb6613a7211ce0eb 100755 --- a/scripts/floatup.py +++ b/scripts/floatup.py @@ -15,37 +15,6 @@ import yaml import zlib -# The Vagrant "insecure" SSH key that is used to log onto the VMs. -INSECURE_PRIVATE_KEY = '''-----BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI -w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP -kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2 -hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO -Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW -yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd -ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1 -Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf -TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK -iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A -sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf -4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP -cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk -EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN -CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX -3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG -YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj -3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+ -dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz -6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC -P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF -llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ -kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH -+vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ -NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s= ------END RSA PRIVATE KEY----- -''' - - def parse_inventory(path, host_attrs): with open(path) as fd: inventory = yaml.safe_load(fd) @@ -87,16 +56,24 @@ def encode_dashboard_request(req): return base64.urlsafe_b64encode(comp.flush()).decode('ascii') -def install_vagrant_ssh_key(): - # Install the SSH key as Vagrant would do, for compatibility. - key_path = os.path.join( - os.getenv('HOME'), '.vagrant.d', 'insecure_private_key') - if os.path.exists(key_path): - return - os.makedirs(os.path.dirname(key_path), mode=0o700, exist_ok=True) - with open(key_path, 'w') as fd: - fd.write(INSECURE_PRIVATE_KEY) - os.chmod(key_path, 0o600) +def generate_ssh_key(): + path = '/root/.ssh/temp' + if os.getenv('HOME'): + path = os.getenv('HOME') + '/.ssh/temp' + os.makedirs(os.path.dirname(path), mode=0o700, exist_ok=True) + subprocess.check_call(['ssh-keygen', '-t', 'ed25519', '-f', path, '-C', '', '-N', '']) + return path + + +def generate_ssh_config(inventory, private_key_path): + netglob = re.sub(r'\.0/24$', '.*', inventory['network']) + return f''' +Host {netglob} + User root + IdentityFile {private_key_path} + StrictHostKeyChecking no + UserKnownHostsFile /dev/null +''' def main(): @@ -135,8 +112,11 @@ def main(): help='vmine dashboard base URL (for Gitlab CI)') parser.add_argument( '--ssh-key', metavar='FILE', - type=argparse.FileType('r'), help='root SSH key to install on VMs') + parser.add_argument( + '--ssh-config', metavar='FILE', + default='/root/.ssh/config', + help='append SSH config to this file') parser.add_argument( '--name', metavar='NAME', help='group name (for named groups)') @@ -153,14 +133,19 @@ def main(): host_attrs['cpu'] = args.cpu if args.image: host_attrs['image'] = args.image + req = parse_inventory(args.inventory, host_attrs) req['ttl'] = args.ttl if args.name: req['name'] = args.name if args.ssh_key: - req['ssh_key'] = args.ssh_key + ssh_key_path = args.ssh_key else: - install_vagrant_ssh_key() + ssh_key_path = generate_ssh_key() + with open(ssh_key_path + '.pub', 'r') as fd: + req['ssh_key'] = fd.read().strip() + + os.umask(0o077) print(f'creating VM group with attrs {host_attrs} ...') print(f'vmine request: {req}') @@ -170,13 +155,20 @@ def main(): fd.write(group_id) print(f'created VM group {group_id}') + if args.ssh_config: + print(f'updating ssh config') + with open(args.ssh_config, 'a') as fd: + fd.write(generate_ssh_config(req, ssh_key_path)) + if args.env: with open(args.env, 'w') as fd: fd.write(f'VMINE_ID={group_id}\n') if args.dashboard_url: base_url = args.dashboard_url.rstrip('/') payload = encode_dashboard_request(req) - fd.write(f'VMINE_GROUP_URL={base_url}/dash/{payload}\n') + dashboard_url = f'{base_url}/dash/{payload}' + fd.write(f'VMINE_GROUP_URL={dashboard_url}\n') + print(f'dashboard URL: {dashboard_url}') elif args.cmd == 'down': req = {} @@ -192,8 +184,11 @@ def main(): return req['group_id'] = group_id print(f'stopping VM group {group_id}...') - do_request(args.url + '/api/stop-group', args.ssh, req) - if args.state_file: + try: + do_request(args.url + '/api/stop-group', args.ssh, req) + except: + pass + if args.state_file and os.path.exists(args.state_file): os.remove(args.state_file)