1111e30c0SFam Zheng#!/usr/bin/env python 2111e30c0SFam Zheng# 3111e30c0SFam Zheng# FreeBSD VM image 4111e30c0SFam Zheng# 5*918fb8faSGerd Hoffmann# Copyright 2017-2019 Red Hat Inc. 6111e30c0SFam Zheng# 7111e30c0SFam Zheng# Authors: 8111e30c0SFam Zheng# Fam Zheng <famz@redhat.com> 9*918fb8faSGerd Hoffmann# Gerd Hoffmann <kraxel@redhat.com> 10111e30c0SFam Zheng# 11111e30c0SFam Zheng# This code is licensed under the GPL version 2 or later. See 12111e30c0SFam Zheng# the COPYING file in the top-level directory. 13111e30c0SFam Zheng# 14111e30c0SFam Zheng 15111e30c0SFam Zhengimport os 16*918fb8faSGerd Hoffmannimport re 17111e30c0SFam Zhengimport sys 18*918fb8faSGerd Hoffmannimport time 19*918fb8faSGerd Hoffmannimport socket 20111e30c0SFam Zhengimport subprocess 21111e30c0SFam Zhengimport basevm 22111e30c0SFam Zheng 23111e30c0SFam Zhengclass FreeBSDVM(basevm.BaseVM): 24111e30c0SFam Zheng name = "freebsd" 2531719c37SPhilippe Mathieu-Daudé arch = "x86_64" 26*918fb8faSGerd Hoffmann 27*918fb8faSGerd Hoffmann link = "https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-disc1.iso.xz" 28*918fb8faSGerd Hoffmann csum = "1d40015bea89d05b8bd13e2ed80c40b522a9ec1abd8e7c8b80954fb485fb99db" 29*918fb8faSGerd Hoffmann size = "20G" 30*918fb8faSGerd Hoffmann pkgs = [ 31*918fb8faSGerd Hoffmann # build tools 32*918fb8faSGerd Hoffmann "git", 33*918fb8faSGerd Hoffmann "pkgconf", 34*918fb8faSGerd Hoffmann "bzip2", 35*918fb8faSGerd Hoffmann 36*918fb8faSGerd Hoffmann # gnu tools 37*918fb8faSGerd Hoffmann "bash", 38*918fb8faSGerd Hoffmann "gmake", 39*918fb8faSGerd Hoffmann "gsed", 40*918fb8faSGerd Hoffmann "flex", "bison", 41*918fb8faSGerd Hoffmann 42*918fb8faSGerd Hoffmann # libs: crypto 43*918fb8faSGerd Hoffmann "gnutls", 44*918fb8faSGerd Hoffmann 45*918fb8faSGerd Hoffmann # libs: images 46*918fb8faSGerd Hoffmann "jpeg-turbo", 47*918fb8faSGerd Hoffmann "png", 48*918fb8faSGerd Hoffmann 49*918fb8faSGerd Hoffmann # libs: ui 50*918fb8faSGerd Hoffmann "sdl2", 51*918fb8faSGerd Hoffmann "gtk3", 52*918fb8faSGerd Hoffmann "libxkbcommon", 53*918fb8faSGerd Hoffmann 54*918fb8faSGerd Hoffmann # libs: opengl 55*918fb8faSGerd Hoffmann "libepoxy", 56*918fb8faSGerd Hoffmann "mesa-libs", 57*918fb8faSGerd Hoffmann ] 58*918fb8faSGerd Hoffmann 59111e30c0SFam Zheng BUILD_SCRIPT = """ 60111e30c0SFam Zheng set -e; 61*918fb8faSGerd Hoffmann rm -rf /home/qemu/qemu-test.* 62*918fb8faSGerd Hoffmann cd $(mktemp -d /home/qemu/qemu-test.XXXXXX); 63*918fb8faSGerd Hoffmann mkdir src build; cd src; 64111e30c0SFam Zheng tar -xf /dev/vtbd1; 65*918fb8faSGerd Hoffmann cd ../build 66*918fb8faSGerd Hoffmann ../src/configure --python=python3.6 {configure_opts}; 675c2ec9b6SAlex Bennée gmake --output-sync -j{jobs} {target} {verbose}; 68111e30c0SFam Zheng """ 69111e30c0SFam Zheng 70*918fb8faSGerd Hoffmann def console_boot_serial(self): 71*918fb8faSGerd Hoffmann self.console_wait_send("Autoboot", "3") 72*918fb8faSGerd Hoffmann self.console_wait_send("OK", "set console=comconsole\n") 73*918fb8faSGerd Hoffmann self.console_wait_send("OK", "boot\n") 74*918fb8faSGerd Hoffmann 75111e30c0SFam Zheng def build_image(self, img): 76*918fb8faSGerd Hoffmann self.print_step("Downloading install iso") 77*918fb8faSGerd Hoffmann cimg = self._download_with_cache(self.link, sha256sum=self.csum) 78111e30c0SFam Zheng img_tmp = img + ".tmp" 79*918fb8faSGerd Hoffmann iso = img + ".install.iso" 80*918fb8faSGerd Hoffmann iso_xz = iso + ".xz" 81*918fb8faSGerd Hoffmann 82*918fb8faSGerd Hoffmann self.print_step("Preparing iso and disk image") 83*918fb8faSGerd Hoffmann subprocess.check_call(["cp", "-f", cimg, iso_xz]) 84*918fb8faSGerd Hoffmann subprocess.check_call(["xz", "-dvf", iso_xz]) 85*918fb8faSGerd Hoffmann subprocess.check_call(["qemu-img", "create", "-f", "qcow2", 86*918fb8faSGerd Hoffmann img_tmp, self.size]) 87*918fb8faSGerd Hoffmann 88*918fb8faSGerd Hoffmann self.print_step("Booting installer") 89*918fb8faSGerd Hoffmann self.boot(img_tmp, extra_args = [ 90*918fb8faSGerd Hoffmann "-bios", "pc-bios/bios-256k.bin", 91*918fb8faSGerd Hoffmann "-machine", "graphics=off", 92*918fb8faSGerd Hoffmann "-cdrom", iso 93*918fb8faSGerd Hoffmann ]) 94*918fb8faSGerd Hoffmann self.console_init() 95*918fb8faSGerd Hoffmann self.console_boot_serial() 96*918fb8faSGerd Hoffmann self.console_wait_send("Console type", "xterm\n") 97*918fb8faSGerd Hoffmann 98*918fb8faSGerd Hoffmann # pre-install configuration 99*918fb8faSGerd Hoffmann self.console_wait_send("Welcome", "\n") 100*918fb8faSGerd Hoffmann self.console_wait_send("Keymap Selection", "\n") 101*918fb8faSGerd Hoffmann self.console_wait_send("Set Hostname", "freebsd\n") 102*918fb8faSGerd Hoffmann self.console_wait_send("Distribution Select", "\n") 103*918fb8faSGerd Hoffmann self.console_wait_send("Partitioning", "\n") 104*918fb8faSGerd Hoffmann self.console_wait_send("Partition", "\n") 105*918fb8faSGerd Hoffmann self.console_wait_send("Scheme", "\n") 106*918fb8faSGerd Hoffmann self.console_wait_send("Editor", "f") 107*918fb8faSGerd Hoffmann self.console_wait_send("Confirmation", "c") 108*918fb8faSGerd Hoffmann 109*918fb8faSGerd Hoffmann self.print_step("Installation started now, this will take a while") 110*918fb8faSGerd Hoffmann 111*918fb8faSGerd Hoffmann # post-install configuration 112*918fb8faSGerd Hoffmann self.console_wait("New Password:") 113*918fb8faSGerd Hoffmann self.console_send("%s\n" % self.ROOT_PASS) 114*918fb8faSGerd Hoffmann self.console_wait("Retype New Password:") 115*918fb8faSGerd Hoffmann self.console_send("%s\n" % self.ROOT_PASS) 116*918fb8faSGerd Hoffmann 117*918fb8faSGerd Hoffmann self.console_wait_send("Network Configuration", "\n") 118*918fb8faSGerd Hoffmann self.console_wait_send("IPv4", "y") 119*918fb8faSGerd Hoffmann self.console_wait_send("DHCP", "y") 120*918fb8faSGerd Hoffmann self.console_wait_send("IPv6", "n") 121*918fb8faSGerd Hoffmann self.console_wait_send("Resolver", "\n") 122*918fb8faSGerd Hoffmann 123*918fb8faSGerd Hoffmann self.console_wait_send("Time Zone Selector", "a\n") 124*918fb8faSGerd Hoffmann self.console_wait_send("Confirmation", "y") 125*918fb8faSGerd Hoffmann self.console_wait_send("Time & Date", "\n") 126*918fb8faSGerd Hoffmann self.console_wait_send("Time & Date", "\n") 127*918fb8faSGerd Hoffmann 128*918fb8faSGerd Hoffmann self.console_wait_send("System Configuration", "\n") 129*918fb8faSGerd Hoffmann self.console_wait_send("System Hardening", "\n") 130*918fb8faSGerd Hoffmann 131*918fb8faSGerd Hoffmann # qemu user 132*918fb8faSGerd Hoffmann self.console_wait_send("Add User Accounts", "y") 133*918fb8faSGerd Hoffmann self.console_wait("Username") 134*918fb8faSGerd Hoffmann self.console_send("%s\n" % self.GUEST_USER) 135*918fb8faSGerd Hoffmann self.console_wait("Full name") 136*918fb8faSGerd Hoffmann self.console_send("%s\n" % self.GUEST_USER) 137*918fb8faSGerd Hoffmann self.console_wait_send("Uid", "\n") 138*918fb8faSGerd Hoffmann self.console_wait_send("Login group", "\n") 139*918fb8faSGerd Hoffmann self.console_wait_send("Login group", "\n") 140*918fb8faSGerd Hoffmann self.console_wait_send("Login class", "\n") 141*918fb8faSGerd Hoffmann self.console_wait_send("Shell", "\n") 142*918fb8faSGerd Hoffmann self.console_wait_send("Home directory", "\n") 143*918fb8faSGerd Hoffmann self.console_wait_send("Home directory perm", "\n") 144*918fb8faSGerd Hoffmann self.console_wait_send("Use password", "\n") 145*918fb8faSGerd Hoffmann self.console_wait_send("Use an empty password", "\n") 146*918fb8faSGerd Hoffmann self.console_wait_send("Use a random password", "\n") 147*918fb8faSGerd Hoffmann self.console_wait("Enter password:") 148*918fb8faSGerd Hoffmann self.console_send("%s\n" % self.GUEST_PASS) 149*918fb8faSGerd Hoffmann self.console_wait("Enter password again:") 150*918fb8faSGerd Hoffmann self.console_send("%s\n" % self.GUEST_PASS) 151*918fb8faSGerd Hoffmann self.console_wait_send("Lock out", "\n") 152*918fb8faSGerd Hoffmann self.console_wait_send("OK", "yes\n") 153*918fb8faSGerd Hoffmann self.console_wait_send("Add another user", "no\n") 154*918fb8faSGerd Hoffmann 155*918fb8faSGerd Hoffmann self.console_wait_send("Final Configuration", "\n") 156*918fb8faSGerd Hoffmann self.console_wait_send("Manual Configuration", "\n") 157*918fb8faSGerd Hoffmann self.console_wait_send("Complete", "\n") 158*918fb8faSGerd Hoffmann 159*918fb8faSGerd Hoffmann self.print_step("Installation finished, rebooting") 160*918fb8faSGerd Hoffmann self.console_boot_serial() 161*918fb8faSGerd Hoffmann 162*918fb8faSGerd Hoffmann # setup qemu user 163*918fb8faSGerd Hoffmann prompt = "$" 164*918fb8faSGerd Hoffmann self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) 165*918fb8faSGerd Hoffmann self.console_wait_send(prompt, "exit\n") 166*918fb8faSGerd Hoffmann 167*918fb8faSGerd Hoffmann # setup root user 168*918fb8faSGerd Hoffmann prompt = "root@freebsd:~ #" 169*918fb8faSGerd Hoffmann self.console_ssh_init(prompt, "root", self.ROOT_PASS) 170*918fb8faSGerd Hoffmann self.console_sshd_config(prompt) 171*918fb8faSGerd Hoffmann 172*918fb8faSGerd Hoffmann # setup serial console 173*918fb8faSGerd Hoffmann self.console_wait(prompt) 174*918fb8faSGerd Hoffmann self.console_send("echo 'console=comconsole' >> /boot/loader.conf\n") 175*918fb8faSGerd Hoffmann 176*918fb8faSGerd Hoffmann # setup boot delay 177*918fb8faSGerd Hoffmann self.console_wait(prompt) 178*918fb8faSGerd Hoffmann self.console_send("echo 'autoboot_delay=1' >> /boot/loader.conf\n") 179*918fb8faSGerd Hoffmann 180*918fb8faSGerd Hoffmann # setup virtio-blk #1 (tarfile) 181*918fb8faSGerd Hoffmann self.console_wait(prompt) 182*918fb8faSGerd Hoffmann self.console_send("echo 'chmod 666 /dev/vtbd1' >> /etc/rc.local\n") 183*918fb8faSGerd Hoffmann 184*918fb8faSGerd Hoffmann self.print_step("Configuration finished, rebooting") 185*918fb8faSGerd Hoffmann self.console_wait_send(prompt, "reboot\n") 186*918fb8faSGerd Hoffmann self.console_wait("login:") 187*918fb8faSGerd Hoffmann self.wait_ssh() 188*918fb8faSGerd Hoffmann 189*918fb8faSGerd Hoffmann self.print_step("Installing packages") 190*918fb8faSGerd Hoffmann self.ssh_root_check("pkg install -y %s\n" % " ".join(self.pkgs)) 191*918fb8faSGerd Hoffmann 192*918fb8faSGerd Hoffmann # shutdown 193*918fb8faSGerd Hoffmann self.ssh_root(self.poweroff) 194*918fb8faSGerd Hoffmann self.console_wait("Uptime:") 195*918fb8faSGerd Hoffmann self.wait() 196*918fb8faSGerd Hoffmann 197*918fb8faSGerd Hoffmann if os.path.exists(img): 198*918fb8faSGerd Hoffmann os.remove(img) 199111e30c0SFam Zheng os.rename(img_tmp, img) 200*918fb8faSGerd Hoffmann os.remove(iso) 201*918fb8faSGerd Hoffmann self.print_step("All done") 202111e30c0SFam Zheng 203111e30c0SFam Zhengif __name__ == "__main__": 204111e30c0SFam Zheng sys.exit(basevm.main(FreeBSDVM)) 205