LXD Provision by Yaml

From UVOO Tech Wiki
Jump to navigation Jump to search

main.py

import yaml  # pyyaml
from yaml import load, dump
from subprocess import Popen, PIPE
import time

try:
    from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
    from yaml import Loader, Dumper

with open(r'config.yml') as f:
    config = yaml.safe_load(f)


def prep_rhel(name):
    process = Popen(['lxc', 'exec', name, '--', 'yum', 'install', '-y', 'openssh-server'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    process = Popen(['lxc', 'exec', name, '--', 'systemctl', 'start', 'sshd'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    process = Popen(['lxc', 'exec', name, '--', 'bash', '-c', 'if [ ! -d /root/.ssh ]; then mkdir -p /root/.ssh; fi'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    process = Popen(['lxc', 'exec', name, '--', 'bash', '-c', 'if [ ! -d /root/.ssh ]; then mkdir -p /root/.ssh; fi'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    process = Popen(['lxc', 'exec', name, '--', 'bash', '-c', 'if [ ! -f /root/.ssh/authorized_keys ]; then touch /root/.ssh/authorized_keys; fi'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()

def create_container(c):
    lxd_ipv4 = config['lxd']['ipv4']
    lxd_bridge = config['lxd']['bridge']
    authorized_keys = c['authorized_keys']
    image = c['image']
    name = c['name']
    proxy = c['proxy']
    ipv4 = c['ipv4']
    process = Popen(['lxc', 'init', image, name], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    # if len(stdout.decode()) != 0:
    #     print(stdout.decode())

    process = Popen(['lxc', 'network', 'attach', lxd_bridge, name, 'eth0', 'eth0'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    if len(stdout.decode()) != 0:
        print(stdout.decode())

    process = Popen(['lxc', 'config', 'device', 'set', name, 'eth0', 'ipv4.address', ipv4], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    if len(stdout.decode()) != 0:
        print(stdout.decode())

    for p in proxy:
        src_port = p.split(':')[0]
        dst_port = p.split(':')[1]
        process = Popen(['lxc', 'config', 'device', 'add', name, f'proxy4_tcp{dst_port}', 'proxy', 'nat=true', f'listen=tcp:{lxd_ipv4}:{src_port}', f'connect=tcp:0.0.0.0:{dst_port}'], stdout=PIPE, stderr=PIPE)
        stdout, stderr = process.communicate()
        if len(stdout.decode()) != 0:
            print(stdout.decode())

    process = Popen(['lxc', 'start', name], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    if len(stdout.decode()) != 0:
        print(stdout.decode())
    process = Popen(['lxc', 'exec', name, '--', 'bash', '-c', 'while [ ! -d /root ]; do sleep 2; done'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    if "centos" in image.lower() or "rhel" in image.lower():
        prep_rhel(name)

    process = Popen(['lxc', 'exec', name, '--', 'bash', '-c', 'while [ ! -f /root/.ssh/authorized_keys ]; do sleep 2; done'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()

    for authorized_key in authorized_keys:
        process = Popen(['lxc', 'exec', name, '--', 'bash', '-c', f'grep \"{authorized_key}\" /root/.ssh/authorized_keys || echo {authorized_key} >> /root/.ssh/authorized_keys'], stdout=PIPE, stderr=PIPE)
        stdout, stderr = process.communicate()
        # print(stdout.decode(), stderr.decode())
    # print(f"Successfully created container {name}.")


def list_containers():
    process = Popen(['lxc', 'list'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    print(stdout.decode())


def main():
    for container_name in config['containers']:
        container = config['containers'][container_name]
        create_container(container)
    list_containers()


if __name__ == "__main__":
    main()

config.yml

lxd:
  ipv4: 10.206.225.171
  bridge: lxdbr0
containers:
  u3:
    name: u3
    image: ubuntu:20.04
    ipv4: 172.16.0.31
    proxy:
      - "7777:22"
      - "7778:22"
    authorized_keys:
      - ssh-ed25519
      - ssh-lxd
  u4:
    name: u4
    image: ubuntu:20.04
    ipv4: 172.16.0.32
    proxy:
      - "7779:22"
    authorized_keys:
      - ssh-ed25519
      - ssh-
  c1:
    name: c1
    image: images:centos/8/amd64
    ipv4: 172.16.0.33
    proxy:
      - "7780:22"
    authorized_keys:
      - ssh-ed25519
      - ssh-