import argparse import pathlib import subprocess MD_PATH = "./meta-data" UD_PATH = "./user-data" ND_PATH = "./network-config" def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--password", required=True) parser.add_argument("--public-key", required=True, type=open) parser.add_argument("--local-hostname", default="aio3.gpslab.cbr.redhat.com") parser.add_argument("--user-data", default="./user-data.tpl", type=open) parser.add_argument("--meta-data", default="./meta-data.tpl", type=open) parser.add_argument("--network-data", default="./network-config.tpl", type=open) parser.add_argument("--instance-id", default="aio3") parser.add_argument("--output-image", required=True) parser.add_argument("--image-size", default="100G") parser.add_argument("--input-image", required=True) parser.add_argument("--os-variant", required=True) parser.add_argument("--name", required=True) parser.add_argument("--memory", default=2048) #, type="int") parser.add_argument("--gateway", required=True) parser.add_argument("--cidr-1", required=True) parser.add_argument("--cidr-2", required=True) parser.add_argument("--dns", required=True) parser.add_argument("--search-domain", required=True) parser.add_argument("-v", "--verbose", action="store_true") args = parser.parse_args() args.public_key = args.public_key.read() args.user_data = args.user_data.read() args.user_data = args.user_data.format(data=args) args.meta_data = args.meta_data.read() args.meta_data = args.meta_data.format(data=args) args.network_data = args.network_data.read() args.network_data = args.network_data.format(data=args) output_image = pathlib.Path(args.output_image) if output_image.exists(): raise ValueError(f"{args.output_image} already exists") args.output_image = output_image input_image = pathlib.Path(args.input_image) if not input_image.exists(): raise ValueError(f"{args.input_image} not found") args.input_image = input_image return args def write_user_data(user_data): with open(UD_PATH, "w", encoding="utf-8") as user_data_file: user_data_file.write(user_data) def write_meta_data(meta_data): with open(MD_PATH, "w", encoding="utf-8") as meta_data_file: meta_data_file.write(meta_data) def write_network_data(network_data): with open(ND_PATH, "w", encoding="utf-8") as network_data_file: network_data_file.write(network_data) def create_image(args): print("creating image") cmd = f"qemu-img create -f qcow2 -o preallocation=metadata {args.output_image} {args.image_size}" result = subprocess.check_output(cmd, shell=True, universal_newlines=True) if args.verbose: print(result) print("Resizing image") cmd = f"virt-resize --expand /dev/sda3 {args.input_image} {args.output_image}" result= subprocess.check_output(cmd, shell=True, universal_newlines=True) if args.verbose: print(result) def virt_install_cmd(args): cmd = f""" sudo virt-install \\ --os-variant {args.os_variant} \\ --name {args.name} \\ --memory {args.memory} \\ --disk {args.output_image} \\ --import \\ --graphics spice,listen=127.0.0.1 \\ --video virtio \\ --channel spicevmc \\ --wait 0 \\ --cloud-init meta-data=./meta-data,user-data=./user-data \\ --network bridge=bridge0 \\ --network bridge=bridge0 """ print("running virt-install") if args.verbose: print(cmd) result =subprocess.check_output(cmd, shell=True, universal_newlines=True) if args.verbose: print(result) def delete_meta_data(): pathlib.Path.unlink(pathlib.Path(MD_PATH)) def delete_user_data(): pathlib.Path.unlink(pathlib.Path(UD_PATH)) def install_packages(args): cmd = "sudo dnf install -y virt-install virt-viewer qemu-img libguestfs.x86_64" print("installing needed packages...") if args.verbose: print(subprocess.check_output(cmd, shell=True, universal_newlines=True)) def main(): args = parse_args() if args.verbose: print(args) install_packages(args) create_image(args) write_meta_data(args.meta_data) write_user_data(args.user_data) virt_install_cmd(args) delete_meta_data() delete_user_data() if __name__ == '__main__': main()