[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 2/7] 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.
---
 ts-freebsd-host-install | 237 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)
 create mode 100755 ts-freebsd-host-install

diff --git a/ts-freebsd-host-install b/ts-freebsd-host-install
new file mode 100755
index 0000000..8ff9be5
--- /dev/null
+++ b/ts-freebsd-host-install
@@ -0,0 +1,237 @@
+#!/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;
+
+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);
+
+# TODO: this should be runvars
+our ($version) = grep /version=/, @ARGV;
+$version =~ s/version=//;
+logm("Installing FreeBSD version: $version");
+
+# List of FreeBSD mirrors, obtained from:
+# http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/mirrors-ftp.html
+# 13/08/2014
+our @ftp_hosts = qw(ftp.freebsd.org ftp1.freebsd.org ftp2.freebsd.org
+                    ftp3.freebsd.org ftp4.freebsd.org ftp5.freebsd.org
+                    ftp6.freebsd.org ftp7.freebsd.org ftp10.freebsd.org
+                    ftp11.freebsd.org ftp13.freebsd.org ftp14.freebsd.org
+                    ftp1.am.freebsd.org ftp.au.freebsd.org ftp2.au.freebsd.org
+                    ftp3.au.freebsd.org ftp.at.freebsd.org ftp2.br.freebsd.org
+                    ftp3.br.freebsd.org ftp4.br.freebsd.org ftp.ca.freebsd.org
+                    ftp2.ca.freebsd.org ftp.cn.freebsd.org ftp.cz.freebsd.org
+                    ftp2.cz.freebsd.org ftp.dk.freebsd.org ftp.ee.freebsd.org
+                    ftp.fi.freebsd.org ftp.fr.freebsd.org ftp1.fr.freebsd.org
+                    ftp3.fr.freebsd.org ftp5.fr.freebsd.org ftp6.fr.freebsd.org
+                    ftp7.fr.freebsd.org ftp8.fr.freebsd.org ftp.de.freebsd.org
+                    ftp1.de.freebsd.org ftp2.de.freebsd.org ftp4.de.freebsd.org
+                    ftp5.de.freebsd.org ftp7.de.freebsd.org ftp8.de.freebsd.org
+                    ftp.gr.freebsd.org ftp2.gr.freebsd.org ftp.hk.freebsd.org
+                    ftp3.ie.freebsd.org ftp.jp.freebsd.org ftp2.jp.freebsd.org
+                    ftp3.jp.freebsd.org ftp4.jp.freebsd.org ftp5.jp.freebsd.org
+                    ftp6.jp.freebsd.org ftp7.jp.freebsd.org ftp8.jp.freebsd.org
+                    ftp9.jp.freebsd.org ftp.kr.freebsd.org ftp2.kr.freebsd.org
+                    ftp.nl.freebsd.org ftp2.nl.freebsd.org ftp.nz.freebsd.org
+                    ftp.no.freebsd.org ftp.pl.freebsd.org ftp.ru.freebsd.org
+                    ftp2.ru.freebsd.org ftp4.ru.freebsd.org ftp5.ru.freebsd.org
+                    ftp6.ru.freebsd.org ftp.si.freebsd.org ftp.za.freebsd.org
+                    ftp2.za.freebsd.org ftp4.za.freebsd.org ftp.es.freebsd.org
+                    ftp3.es.freebsd.org ftp.se.freebsd.org ftp2.se.freebsd.org
+                    ftp.ch.freebsd.org ftp.tw.freebsd.org ftp2.tw.freebsd.org
+                    ftp4.tw.freebsd.org ftp5.tw.freebsd.org ftp.ua.freebsd.org
+                    ftp6.ua.freebsd.org ftp7.ua.freebsd.org ftp.uk.freebsd.org
+                    ftp2.uk.freebsd.org ftp3.uk.freebsd.org ftp4.uk.freebsd.org
+                    ftp5.uk.freebsd.org ftp1.us.freebsd.org ftp2.us.freebsd.org
+                    ftp3.us.freebsd.org ftp4.us.freebsd.org 
ftp5.us.freebsd.org);
+
+# TODO: this has to be set on a per-host basis.
+# It should probably come from $ho?
+our @disk_names = qw(ada0 da0 ad0);
+
+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);
+
+    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', 900, "root");
+
+    logm('Setting up ssh keys for remote access');
+    target_cmd_root_with_password($ho, <<END, 900, "root");
+        set -e
+        mkdir -p ~/.ssh
+        cat <<ENDKEYS >~/.ssh/authorized_keys
+$authkeys
+ENDKEYS
+END
+
+    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";
+
+    logm("Searching for a mirror");
+    foreach my $test_ftp (@ftp_hosts) {
+        logm("Probing mirror $test_ftp");
+        # Test from the target system.
+        my $output = target_cmd_output_root($ho,
+            'nc -zw 10 '.$test_ftp.' 21 >/dev/null 2>&1 && echo "yes" || echo 
"no"',
+            200);
+        if ($output eq "yes") {
+            logm("Found a valid mirror: $test_ftp");
+            $ftp = $test_ftp;
+            last;
+        }
+    }
+    length($ftp) or die "Unable to find a valid ftp mirror, exiting";
+
+    logm('Install of base system using ZFS on root');
+    target_cmd_root($ho, <<END,2400);
+            set -e
+            gpart destroy -F $disk || true
+            zfsinstall -d $disk -u 
ftp://$ftp/pub/FreeBSD/releases/$r{arch}/$version -s 4g
+END
+
+    logm('Setting up ssh and keys for the installed system');
+    target_cmd_root($ho, <<END, 900);
+            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, 900);
+            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, 900);
+            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
+
+    logm('Setting up miscellaneous settings');
+    target_cmd_root($ho, <<END, 900);
+            set -e
+            cp /mnt/usr/share/zoneinfo/Europe/London /mnt/etc/localtime
+            echo 'sendmail_enable="NONE"' >> /mnt/etc/rc.conf
+END
+
+    logm('Copying installer keys into the system');
+    target_cmd_root($ho, 'cp /etc/ssh/*_key* /mnt/etc/ssh/', 900);
+
+    logm('Rebooting into the installed system');
+    target_reboot($ho);
+
+    logm('Setting root shell to /bin/sh');
+    target_cmd_root($ho, 'chsh -s /bin/sh', 900);
+    logm('Adding osstest user');
+    target_cmd_root($ho, 'pw useradd osstest -m', 900);
+    target_cmd_root($ho, <<END, 900);
+            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');
+}
+
+sub setup_pxeboot_firstboot() {
+    my $mfs= 
'freebsd/'.$version.'/'.$r{arch}.'/'.'mfsbsd-'.$version.'-'.$r{arch}.'.img';
+
+    logm('Using mfsBSD image: ' . $mfs);
+
+    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
+}
+
+install();
-- 
1.9.3 (Apple Git-50)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.