[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 4/8] osstest: add a FreeBSD host install recipe
The installation is performed using the bsdinstall tool, which is part of the FreeBSD base system. The installer image is setup with the osstest ssh keys and sshd enabled by default, which allows the test harness to just ssh into the box, create the install config file and launch the scripted install. Currently the installation is done with ZFS only, in stripe mode, and a single disk. In order to support the FreeBSD installer a new method is added, that allows setting the pxe boot of a host using a memdisk. The install script either picks the binary images from the output of a previous FreeBSD buildjob (yet to be introduced), or from the folder pointed by freebsd_distpath. This folder should contain the installer image (install.img) and the compressed install sets (kernel.txz, base.txz) together with the MANIFEST file that contains the checksums. Note that the FreeBSD installer image uses "memdisk" from pxelinux, so the tftp root needs to provide a copy of memdisk. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Changes since v2: - Use sysrc instead of echo to modify rc.conf. Changes since v1: - Use pkg bootstrap instead of pkg update. - Use freebsdbuildjob instead of freebsd_buildjob. - add "append raw" to the memdisk command line. - Use with-lock-ex instead of flock. - Use system_checked and an array to hold the locked command to execute. - Use an array to store the list of possible disk devices. - Use target_putfilecontents_root_stash in order to upload the install script to the target. - Remove the usage of TftpFreeBSDBase. - Use target_tftp_prefix in order to get the prefix for the tftp target image path. - Add a missing linewrap. - Replace the split used to get the runvar paths with a regexp. - Place the install sets at /root/osstest_sets instead of /tmp/osstest_sets. - Pick the sets/installer image from the freebsdbuildjob path_freebsdist or from the runvar variable freebsd_distpath. - Add a comment about which FreeBSD specific inputs the script consumes. --- Osstest/TestSupport.pm | 22 +++- ts-freebsd-host-install | 269 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 290 insertions(+), 1 deletion(-) create mode 100755 ts-freebsd-host-install diff --git a/Osstest/TestSupport.pm b/Osstest/TestSupport.pm index 8b41a4bc..ba1d6cc9 100644 --- a/Osstest/TestSupport.pm +++ b/Osstest/TestSupport.pm @@ -118,7 +118,7 @@ BEGIN { await_webspace_fetch_byleaf create_webfile file_link_contents get_timeout setup_netboot_di setup_netboot_local host_netboot_file - subst_netboot_template + subst_netboot_template setup_netboot_memdisk ether_prefix @@ -2559,6 +2559,26 @@ default local END } +sub setup_netboot_memdisk ($$) { + my ($ho, $img) = @_; + setup_netboot_bootcfg($ho, <<END); +serial 0 $c{Baud} +timeout 5 +label overwrite + menu label ^Overwrite + menu default + kernel memdisk + initrd $img + # NB: according to the memdisk syslinux wikipage [0] + # adding "append raw" is required in order to boot on + # some boxes, and in fact some hardware will not boot + # without it. + # [0] http://www.syslinux.org/wiki/index.php?title=MEMDISK#Memory_access_method + append raw +default overwrite +END +} + # uboot emulates pxelinux, so reuse BIOS stuff sub setup_netboot_di_uboot ($$$$$;%) { return &setup_netboot_di_bios; } sub setup_netboot_local_uboot ($) { return &setup_netboot_local_bios; } diff --git a/ts-freebsd-host-install b/ts-freebsd-host-install new file mode 100755 index 00000000..19254c8c --- /dev/null +++ b/ts-freebsd-host-install @@ -0,0 +1,269 @@ +#!/usr/bin/perl -w +# This is part of "osstest", an automated testing framework for Xen. +# Copyright (C) 2017 Citrix Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# The FreeBSD installer script consumes either one of the following +# runvars: +# +# freebsd_distpath: points to a folder accessible by the controller that +# should contain the installer image and the compressed install sets, +# together with the MANIFEST file. +# +# freebsdbuildjob: points to a previous FreeBSD build job, that has +# produced an installer image and compressed sets. The only runvar used +# form the job pointed to by freebsdbuildjob is the path_freebsddist one, +# that points to the folder containing the files described above. +# +# The installer image must be named 'install.img', and the sets +# 'kernel.txz', 'base.txz' and finally the 'MANIFEST' file that contains +# the checksums. + +use strict qw(vars); +use DBI; +use POSIX; + +unshift @INC, qw(.); +use Osstest; +use Osstest::TestSupport; + +tsreadconfig(); + +our %xopts; + +our ($whhost) = @ARGV; +$whhost ||= 'host'; +our $ho= selecthost($whhost); +exit 0 if $ho->{Flags}{'no-reinstall'}; +exit 0 if $ho->{SharedReady}; + +our $timeout = 1000; + +our @sets = qw(base.txz kernel.txz); + +our $path_prefix = $r{"freebsd_distpath"} || + get_stashed("path_freebsddist", $r{"freebsdbuildjob"}); + +sub get_sets_path () { + my @paths; + + foreach my $set (@sets, "MANIFEST") { + push @paths, { name => "$set", path => "$path_prefix/$set" }; + } + + return @paths; +} + +sub create_ssh_overlay () { + my $url = create_webfile($ho, "ssh.tar", sub { + my ($fh) = @_; + contents_make_cpio($fh, 'ustar', "$c{OverlayLocal}/etc/ssh/"); + }); + + return $url; +} + +sub setup_netboot_installer () { + my $image = "$path_prefix/install.img"; + my $pxeimg = target_tftp_prefix($ho) . "--freebsd.img"; + my $hash = `sha256sum $image | head -c 16` or die $!; + my $tftp_freebsd = "$ho->{Tftp}{Path}/$ho->{Tftp}{TmpDir}/freebsd-images/"; + my $script = <<'END'; +basedir=$0 +imagepath=$1 +sharedpath=$2 +targetpath=$3 +cd $basedir +if [ ! -f $sharedpath ]; then + mkdir -p `dirname $sharedpath` + cp $imagepath $sharedpath +fi +rm -f $targetpath +ln $sharedpath $targetpath +# Dir format from basedir is $arch/$hash/install.img +for hashdir in `find -mindepth 2 -maxdepth 2 -type d`; do + count=`stat -c %h $hashdir/install.img` + if [ $count -eq 1 ]; then + rm -rf $hashdir + fi +done +END + my @cmd = ( "with-lock-ex", "-w", "$tftp_freebsd/lock", + "bash", "-exc", "$script", + "$tftp_freebsd", "$image", "$r{arch}/$hash/install.img", + "$ho->{Tftp}{Path}/$pxeimg" ); + + ensuredir("$tftp_freebsd"); + system_checked(@cmd); + + # Setup the pxelinux config file + logm("Booting from installer image at $pxeimg"); + setup_netboot_memdisk($ho, $pxeimg); +} + +sub install () { + my $authkeys = authorized_keys(); + my $knownhosts = known_hosts(); + my $sshd_keys_url = create_ssh_overlay(); + my @disk_names = qw(ada0 da0 ad0); + my $target_sets = "/root/osstest_sets"; + my $disk; + my $nic; + + target_cmd_root($ho, 'chsh -s /bin/sh', 10); + + logm("Trying to find a disk to install to"); + $disk = target_cmd_output_root($ho, <<END, 30); +for disk in @disk_names; do + if [ -c "/dev/\$disk" ]; then + echo \$disk + exit 0 + fi +done +exit 1 +END + defined($disk) or die "Unable to find a valid disk"; + logm("Using $disk as destination disk device"); + + logm("Trying to figure out primary nic device name"); + $nic = target_cmd_output_root($ho, <<END, 30); +nics=`ifconfig -l` +for nic in \$nics; do + addr=`ifconfig \$nic inet|grep inet|awk {'print \$2'}` + if [ "\$addr" = "$ho->{Ip}" ]; then + echo \$nic + exit 0 + fi +done +exit 1 +END + defined($nic) or die "Unable to find primary network interface"; + logm("Using $nic as primary network interface"); + + logm("Uploading the install sets to the system"); + target_cmd_root($ho, <<END, 30); +mkdir -p $target_sets +mount -o size=1G -t tmpfs tmpfs $target_sets +END + + foreach (get_sets_path()) { + target_putfile_root($ho, 600, $_->{path}, + "$target_sets/$_->{name}"); + } + + logm("Creating the installer script"); + target_putfilecontents_root_stash($ho, 10, <<END, '~/installscript'); +set -a +BSDINSTALL_DISTDIR="$target_sets" +ZFSBOOT_DISKS="$disk" +DISTRIBUTIONS="@sets" +nonInteractive=1 + +#!/bin/sh +set -ex + +# Setup nic and sshd +sysrc ifconfig_$nic=DHCP +sysrc sshd_enable=YES + +# Use syncronious DHCP in case the server is slow +sysrc synchronous_dhclient=YES + +# Disable sendmail +sysrc sendmail_enable=NO +sysrc sendmail_submit_enable=NO +sysrc sendmail_outbound_enable=NO +sysrc sendmail_msp_queue_enable=NO + +# Set proxy for the pkg manager +mkdir -p /usr/local/etc/ +cat << ENDPKG >> /usr/local/etc/pkg.conf +pkg_env: { http_proxy = $c{HttpProxy} } +default_always_yes: true +assume_always_yes: true +ENDPKG + +# Bootstap the package manager +export HTTP_PROXY=$c{HttpProxy} +export ASSUME_ALWAYS_YES=yes +pkg bootstrap + +# Allow root user login and setup ssh keys +chsh -s /bin/sh root +echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config +mkdir -p /root/.ssh +cat << ENDKEYS > /root/.ssh/authorized_keys +$authkeys +ENDKEYS +cat << ENDHOSTS > /root/.ssh/known_hosts +$knownhosts +ENDHOSTS + +# Fetch host keys +fetch $sshd_keys_url -o - | tar -xf - -C /etc/ssh/ +# Set correct permissions +chown root:wheel /etc/ssh/ssh_host_*_key* +chmod 0600 /etc/ssh/ssh_host_*_key +chmod 0644 /etc/ssh/ssh_host_*_key.pub + +# Add a osstest user +pw useradd osstest -m +chsh -s /bin/sh osstest +mkdir -p /home/osstest/.ssh +cat << ENDKEYS > /home/osstest/.ssh/authorized_keys +$authkeys +ENDKEYS +cat << ENDHOSTS > /home/osstest/.ssh/known_hosts +$knownhosts +ENDHOSTS + +# Setup serial console +printf "%s" "-h -S$c{Baud}" >> /boot.config +cat << ENDBOOT >> /boot/loader.conf +boot_serial="YES" +comconsole_speed="$c{Baud}" +console="comconsole" +boot_verbose="YES" +beastie_disable="YES" +ENDBOOT +END + + logm("Launch the installer"); + target_cmd_root($ho, 'bsdinstall script installscript', 1200); + + target_reboot($ho); + + logm("Waiting for the host to boot"); + await_tcp(get_timeout($ho,'reboot',$timeout), 5, $ho); + + logm("FreeBSD installed succesfully"); +} + +# Switch off, setup PXE and switch on to the installer +power_state($ho, 0); +setup_netboot_installer(); +power_cycle_sleep($ho); +power_state($ho, 1); + +# Wait for the host to finish booting +logm("Waiting for the installer to boot"); +await_tcp(get_timeout($ho,'reboot',$timeout), 5, $ho); + +# Next boot will be from local disk +setup_netboot_local($ho); + +# Proceed with the install +install(); + -- 2.11.0 (Apple Git-81) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |