[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 04/11] osstest: add support for installing bare metal FreeBSD
This is done using mfsBSD, which can be booted from pxelinux and contains a script to automatically install FreeBSD using ZFS on root. After the install the host is set to boot from the local disk. Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx> Cc: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> --- Changes since RFC: - Set the bridge to use the MAC from the first added interface instead of generating a random one. - Launch DHCP on the bridge instead of the nic. - Add a list of FreeBSD ftp mirrors and iterate over them in order to find a working one. - Add support for finding the primary disk and nic automatically. - Switch shell to sh (instead of the default csh), and use set -e in order to exit if a command fails. - Replace echo "-Dh" with printf "%s" "-Dh". - Copy installer keys into the installed system in order to prevent it from generating new keys on the first boot. --- production-config | 2 + ts-freebsd-host-install | 283 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+) create mode 100755 ts-freebsd-host-install diff --git a/production-config b/production-config index 515bd98..fefc467 100644 --- a/production-config +++ b/production-config @@ -86,6 +86,8 @@ HostProp_GenEtherPrefixBase 5a:36:0e:00 # :00:01 guest number in job appended # ^^ xor'd with low 8 bits of flight +FreeBSDVersion current + AuthorizedKeysAppend= <<'END' ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq8eHHFJ+XHYgpHxfSdciq0b3tYPdMhHf9CgtwdKGSqCyDyocbn1jX6P0Z535K/JcVaxvaRQbGDl9FZ25neQw6lysE8pGf+G353mgLAE7Lw6xKqlTXDcR0GpKHiZUyY8Ck5AJlGF2MO0cDEzMBx+xkOahDBvAozikUcDHJsTNP+UUIGoRaPeQK0DfgprPkoaLzXFDiZvEoBtYcUUieuNygJt+QVM+ovyTXC68wg5Xb5Ou2PopmDaVMX6/A1HxziTWc3XdhOF5ocuRF/kfWpZL223Auuu/xvNQDly13DhuVlQiU3gRIP7BSCwCdsQC/K68Q6SgfBklKRiqHquYo/QyNQ== osstest@xxxxxxxxxxxxxxxxxxx ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAs6FF9nfzWIlLPeYdqNteJBoYJAcgGxQgeNi7FHYDgWNFhoYPlMPXWOuXhgNxA2/vkX9tUMVZaAh+4WTL1iRBW5B/AS/Ek2O7uM2Uq8v68D2aU9/XalLVnIxssr84pewUmKW8hZfjNnRm99RTQ2Knr2BvtwcHqXtdGYdTYCJkel+FPYQ51yXGRU7dS0D59WapkDFU1tH1Y8s+dRZcRZNRJ5f1w/KO1zx1tOrZRkO3fPlEGNZHVUYfpZLPxz0VX8tOeoaOXhKZO8vSp1pD0L/uaD6FOmugMZxbtq9wEjhZciNCq61ynRf2yt2v9DMu4EAzbW/Ws7OBvWtYj/RHcSxKbw== iwj@xxxxxxxxxxxxxxxxxxx diff --git a/ts-freebsd-host-install b/ts-freebsd-host-install new file mode 100755 index 0000000..2097c66 --- /dev/null +++ b/ts-freebsd-host-install @@ -0,0 +1,283 @@ +#!/usr/bin/perl -w +# This is part of "osstest", an automated testing framework for Xen. +# Copyright (C) 2009-2014 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/>. + +use strict qw(vars); +use DBI; +use POSIX; + +use Osstest; +use Osstest::TestSupport; +use Osstest::Logtailer; + +use File::Basename; +use File::Copy; +use File::Path; +use Cwd 'abs_path'; + +tsreadconfig(); + +our ($whhost) = grep /host=/, @ARGV; +$whhost ||= 'host'; +our $ho= selecthost($whhost); +exit 0 if $ho->{Flags}{'no-reinstall'}; +exit 0 if $ho->{SharedReady}; + +our %timeout= qw(ReadPreseed 350 + Sshd 2400); + +our @disk_names = qw(ada0 da0 ad0); +our @sets = qw(kernel.txz base.txz MANIFEST); + +defined($r{freebsd_buildjob}) or defined($c{FreeBSDVersion}) or + die "don't know which FreeBSD version to install"; + +sub get_mfsbsd() { + + # Figure out the path to the mfsBSD image we have to use. + # This can either come from a previous buildjob or from + # a pre-seeded image. + + if ($r{freebsd_buildjob}) { + # We are going to use the build output from a previous job. + return get_stashed('path_mfsbsd.img', $r{freebsd_buildjob}); + } else { + # We are going to use a pre-seeded version. + return "$c{Images}/freebsd/$c{FreeBSDVersion}/$r{arch}/mfsbsd.img"; + } +} + +sub get_set($) { + my ($set) = @_; + + if ($r{freebsd_buildjob}) { + # We are going to use the build output from a previous job. + return get_stashed("path_$set", $r{freebsd_buildjob}); + } else { + # We are going to use a pre-seeded version. + return "$c{Images}/freebsd/$c{FreeBSDVersion}/$r{arch}/$set"; + } +} + +sub setup_sets() { + my $webfolder = "$c{WebspaceFile}/$c{WebspaceCommon}/freebsd/$ho->{Name}"; + + # Link the sets to the public http folder + rmtree($webfolder); + mkpath($webfolder); + foreach my $set (@sets) { + my $set_src = abs_path(get_set($set)); + logm("Using install set: $set_src"); + symlink $set_src,"$webfolder/$set" or die "Unable to create symlink: $!"; + } +} + +sub setup_pxeboot_firstboot() { + # copy mfsBSD image from the images folder to the tftp folder. + my $mfs_src = get_mfsbsd(); + my $mfs = "$ho->{Tftp}{TmpDir}/mfsbsd-$ho->{Name}.img"; + unlink "$ho->{Tftp}{Path}/$mfs"; + + logm("Using mfsBSD image: $mfs_src"); + copy($mfs_src, "$ho->{Tftp}{Path}/$mfs") or die "Unable to copy image file: $!"; + + setup_pxeboot($ho, <<END); +serial 0 $c{Baud} +timeout 5 +label overwrite + menu label ^Overwrite + menu default + kernel memdisk + append initrd=$mfs +default overwrite +END +} + +sub set_host_keys ($;$) { + my ($restart, $prefix) = @_; + my $target_path; + + if (defined $prefix) { + $target_path = "$prefix/etc/ssh/"; + } else { + $target_path = "/etc/ssh/"; + } + + logm("Copying overlay keys to: $target_path"); + + my @ssh_keys = glob("$c{OverlayLocal}/etc/ssh/*"); + foreach my $key (@ssh_keys) { + target_putfile_root($ho, 10, $key, $target_path, undef, 1); + # Force the usage of the keys that we have uploaded. + # If not mfsBSD/FreeBSD defaults to the automatically generated + # ECDSA key. + if ($key !~ /pub$/) { + $key = basename($key); + target_cmd_root($ho, <<END, 100, 1); + set -e + echo 'HostKey /etc/ssh/$key' >> $target_path/sshd_config +END + } + } + + if ($restart) { + logm("Restarting sshd"); + target_cmd_root($ho, <<END, 100, 1); + set -e + /etc/rc.d/sshd restart +END + } +} + +sub install () { + my $authkeys= authorized_keys(); + my $disk = ""; + my $nic = ""; + my $ftp = ""; + + power_state($ho, 0); + + setup_pxeboot_firstboot(); + + logm('Booting into mfsBSD'); + + sleep(power_cycle_time($ho)); + + power_state($ho, 1); + + # Prepare the sets while the host boots + setup_sets(); + + logm('Waiting for host to boot'); + await_tcp(get_timeout($ho,'boot',$timeout{Sshd}), 22, $ho); + + logm('Setting host to boot from local disk on next boot'); + setup_pxeboot_local($ho); + + logm('Switching root shell to /bin/sh'); + target_cmd_root_with_password($ho, 'chsh -s /bin/sh', 100, "root", 1); + + logm('Setting up ssh keys for remote access'); + target_cmd_root_with_password($ho, <<END, 100, "root", 1); + set -e + mkdir -p ~/.ssh + cat <<ENDKEYS >~/.ssh/authorized_keys +$authkeys +ENDKEYS +END + + set_host_keys(1); + + foreach my $test_disk (@disk_names) { + logm("Probing for $test_disk existence"); + my $output = target_cmd_output_root($ho, + 'test -c /dev/'.$test_disk.' >/dev/null 2>&1 && echo "yes" || echo "no"', + 200); + if ($output eq "yes") { + logm("Found a valid disk device: $test_disk"); + $disk = $test_disk; + last; + } + } + length($disk) or die "Unable to find a valid disk, exiting"; + + my $sets_url = "$c{WebspaceUrl}/$c{WebspaceCommon}/freebsd/$ho->{Name}"; + logm("Install of base system using ZFS on root, using sets from: $sets_url"); + target_cmd_root($ho, <<END,2400); + set -e + gpart destroy -F $disk || true + zfsinstall -d $disk -u $sets_url -s 4g +END + + logm('Setting up ssh and keys for the installed system'); + target_cmd_root($ho, <<END, 100); + set -e + echo 'sshd_enable="YES"' >> /mnt/etc/rc.conf + echo 'PermitRootLogin yes' >> /mnt/etc/ssh/sshd_config + mkdir -p /mnt/root/.ssh + cat <<ENDKEYS >/mnt/root/.ssh/authorized_keys +$authkeys +ENDKEYS +END + + logm('Setting up serial console'); + target_cmd_root($ho, <<END, 100); + set -e + printf "%s" "-Dh" >> /mnt/boot.config + cat <<ENDB >>/mnt/boot/loader.conf +boot_multicons="YES" +boot_serial="YES" +comconsole_speed="$c{Baud}" +console="comconsole,vidconsole" +boot_verbose="YES" +ENDB +END + + logm("Trying to figure out primary nic device name"); + $nic = target_cmd_output_root($ho, + 'ifconfig | grep -B3 '.$ho->{Ip}.' | head -n1 | awk \'{print $1}\'|sed s/://', + 200); + length($nic) or die "Unable to find primary network interface"; + + logm("Using $nic as primary nic interface"); + + logm('Setting up network'); + target_cmd_root($ho, <<END, 100); + set -e + echo "net.link.bridge.inherit_mac=1" >> /mnt/boot/loader.conf + echo 'cloned_interfaces="bridge0"' >> /mnt/etc/rc.conf + echo 'ifconfig_bridge0="addm $nic SYNCDHCP"' >> /mnt/etc/rc.conf + echo 'ifconfig_$nic="up"' >> /mnt/etc/rc.conf +END + + if ($c{HttpProxy}) { + logm("Setting pkg proxy to: $c{HttpProxy}"); + target_cmd_root($ho, <<END, 100); + set -e + mkdir -p /mnt/usr/local/etc/ + echo 'PKG_ENV: { http_proxy = $c{HttpProxy} }' >> /mnt/usr/local/etc/pkg.conf +END + } + + logm('Setting up miscellaneous settings'); + target_cmd_root($ho, <<END, 100); + set -e + cp /mnt/usr/share/zoneinfo/Europe/London /mnt/etc/localtime + echo 'sendmail_enable="NONE"' >> /mnt/etc/rc.conf +END + + set_host_keys(0, "/mnt"); + + logm('Rebooting into the installed system'); + target_reboot($ho); + + logm('Setting root shell to /bin/sh'); + target_cmd_root($ho, 'chsh -s /bin/sh', 100); + logm('Adding osstest user'); + target_cmd_root($ho, 'pw useradd osstest -m', 100); + target_cmd_root($ho, <<END, 100); + set -e + chsh -s /bin/sh osstest + mkdir -p /home/osstest/.ssh + cat <<ENDKEYS >/home/osstest/.ssh/authorized_keys +$authkeys +ENDKEYS +END + + logm('OK: install completed'); +} + +install(); -- 1.9.3 (Apple Git-50) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |