1 #!/usr/bin/bash
   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License, Version 1.0 only
   7 # (the "License").  You may not use this file except in compliance
   8 # with the License.
   9 #
  10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  11 # or http://www.opensolaris.org/os/licensing.
  12 # See the License for the specific language governing permissions
  13 # and limitations under the License.
  14 #
  15 # When distributing Covered Code, include this CDDL HEADER in each
  16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  17 # If applicable, add the following below this CDDL HEADER, with the
  18 # fields enclosed by brackets "[]" replaced with your own identifying
  19 # information: Portions Copyright [yyyy] [name of copyright owner]
  20 #
  21 # CDDL HEADER END
  22 #
  23 #
  24 # Copyright 2012 OmniTI Computer Consulting, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 LOG_SETUP=0
  28 
  29 ConsoleLog(){
  30   exec 4>/dev/console
  31   exec 1>>${1}
  32   exec 2>>${1}
  33   INSTALL_LOG=${1}
  34   LOG_SETUP=1
  35 }
  36 CopyInstallLog(){
  37   if [[ -n "$INSTALL_LOG" ]]; then
  38     cp $INSTALL_LOG $ALTROOT/var/log/install/kayak.log
  39   fi
  40 }
  41 SendInstallLog(){
  42   PUTURL=`echo $CONFIG | sed -e 's%/kayak/%/kayaklog/%g;'`
  43   PUTURL=`echo $PUTURL | sed -e 's%/kayak$%/kayaklog%g;'`
  44   curl -T $INSTALL_LOG $PUTURL/$ETHER
  45 }
  46 OutputLog(){
  47   if [[ "$LOG_SETUP" -eq "0" ]]; then
  48     exec 4>/dev/null
  49     LOG_SETUP=1
  50   fi
  51 }
  52 log() {
  53   OutputLog
  54   TS=`date +%Y/%m/%d-%H:%M:%S`
  55   echo "[$TS] $*" 1>&4
  56   echo "[$TS] $*"
  57 }
  58 bomb() {
  59   log
  60   log ======================================================
  61   log "$*"
  62   log ======================================================
  63   if [[ -n "$INSTALL_LOG" ]]; then
  64   log "For more information, check $INSTALL_LOG"
  65   log ======================================================
  66   fi
  67   exit 1
  68 }
  69 
  70 . /kayak/net_help.sh
  71 . /kayak/disk_help.sh
  72 
  73 ICFILE=/tmp/_install_config
  74 getvar(){
  75   prtconf -v /devices | sed -n '/'$1'/{;n;p;}' | cut -f2 -d\'
  76 }
  77 
  78 # Blank
  79 ROOTPW='$5$kr1VgdIt$OUiUAyZCDogH/uaxH71rMeQxvpDEY2yX.x0ZQRnmeb9'
  80 RootPW(){
  81   ROOTPW="$1"
  82 }
  83 SetRootPW(){
  84   sed -i -e 's%^root::%root:'$ROOTPW':%' $ALTROOT/etc/shadow
  85 }
  86 ForceDHCP(){
  87   log "Forcing all interfaces into DHCP..."
  88   /sbin/ifconfig -a plumb 2> /dev/null
  89   # for the logs
  90   for iface in `/sbin/dladm show-phys -o device -p` ; do
  91     /sbin/ifconfig $iface dhcp &
  92   done
  93   while [[ -z $(/sbin/dhcpinfo BootSrvA) ]]; do
  94     log "Waiting for dhcpinfo..."
  95     sleep 1
  96   done
  97   BOOTSRVA=`/sbin/dhcpinfo BootSrvA`
  98   log "Next server: $BOOTSRVA"
  99   sleep 1
 100 }
 101 
 102 BuildBE() {
 103   BOOTSRVA=`/sbin/dhcpinfo BootSrvA`
 104   MEDIA=`getvar install_media`
 105   MEDIA=`echo $MEDIA | sed -e "s%//\:%//$BOOTSRVA\:%g;"`
 106   MEDIA=`echo $MEDIA | sed -e "s%///%//$BOOTSRVA/%g;"`
 107   zfs set compression=on rpool
 108   zfs create rpool/ROOT
 109   zfs set canmount=off rpool/ROOT
 110   zfs set mountpoint=legacy rpool/ROOT
 111   log "Receiving image: $MEDIA"
 112   curl -s $MEDIA | pv -B 128m | bzip2 -dc | zfs receive -u rpool/ROOT/omnios
 113   zfs set canmount=noauto rpool/ROOT/omnios
 114   zfs set mountpoint=legacy rpool/ROOT/omnios
 115   log "Cleaning up boot environment"
 116   beadm mount omnios /mnt
 117   ALTROOT=/mnt
 118   cp $ALTROOT/lib/svc/seed/global.db $ALTROOT/etc/svc/repository.db
 119   chmod 0600 $ALTROOT/etc/svc/repository.db
 120   chown root:sys $ALTROOT/etc/svc/repository.db
 121   /usr/sbin/devfsadm -r /mnt
 122   [[ -L $ALTROOT/dev/msglog ]] || \
 123     ln -s ../devices/pseudo/sysmsg@0:msglog $ALTROOT/dev/msglog
 124   MakeSwapDump
 125   zfs destroy rpool/ROOT/omnios@kayak
 126 }
 127 
 128 FetchConfig(){
 129   ETHER=`Ether`
 130   BOOTSRVA=`/sbin/dhcpinfo BootSrvA`
 131   CONFIG=`getvar install_config`
 132   CONFIG=`echo $CONFIG | sed -e "s%//\:%//$BOOTSRVA\:%g;"`
 133   CONFIG=`echo $CONFIG | sed -e "s%///%//$BOOTSRVA/%g;"`
 134   L=${#ETHER}
 135   while [[ "$L" -gt "0" ]]; do
 136     URL="$CONFIG/${ETHER:0:$L}"
 137     log "... trying $URL"
 138     /bin/curl -s -o $ICFILE $URL
 139     if [[ -f $ICFILE ]]; then
 140       if [[ -n $(grep BuildRpool $ICFILE) ]]; then
 141         log "fetched config."
 142         return 0
 143       fi
 144       rm -f $ICFILE
 145     fi
 146     L=$(($L - 1))
 147   done
 148   return 1
 149 }
 150 
 151 MakeBootable(){
 152   log "Making boot environment bootable"
 153   zpool set bootfs=rpool/ROOT/omnios rpool
 154   # Must do beadm activate first on the off chance we're bootstrapping from
 155   # GRUB.
 156   beadm activate omnios
 157 
 158   # NOTE:  This installboot loop assumes we're doing GPT whole-disk rpools.
 159   for i in `cat /tmp/kayak-disk-list`
 160   do
 161     installboot -mf /boot/pmbr /boot/gptzfsboot /dev/rdsk/${i}s0
 162   done
 163 
 164   bootadm update-archive -R $ALTROOT
 165   return 0
 166 }
 167 
 168 SetHostname()
 169 {
 170   log "Setting hostname: ${1}"
 171   /bin/hostname "$1"
 172   echo "$1" > $ALTROOT/etc/nodename
 173   head -n 26 $ALTROOT/etc/hosts > /tmp/hosts
 174   echo "::1\t\t$1" >> /tmp/hosts
 175   echo "127.0.0.1\t$1" >> /tmp/hosts
 176   cat /tmp/hosts > $ALTROOT/etc/hosts
 177 }
 178 
 179 AutoHostname() {
 180   suffix=$1
 181   macadr=`/sbin/ifconfig -a | \
 182           /usr/bin/awk '/UP/{if($2 !~ /LOOPBACK/){iface=$1;}} /ether/{if(iface){print $2; exit;}}' | \
 183           /bin/tr '[:upper:]' '[:lower:]' | \
 184           /bin/sed -e 's/^/ 0/g;s/:/-0/g; s/0\([0-9a-f][0-9a-f]\)/\1/g; s/ //g;'`
 185   [ -z $suffix ] && suffix=omnios
 186   [ "$suffix" == "-" ] && suffix= || suffix=-$suffix
 187   SetHostname $macadr$suffix
 188 }
 189 
 190 SetTimezone()
 191 {
 192   log "Setting timezone: ${1}"
 193   sed -i -e "s:^TZ=.*:TZ=${1}:" $ALTROOT/etc/default/init
 194 }
 195 
 196 ApplyChanges(){
 197   SetRootPW
 198   [[ -L $ALTROOT/etc/svc/profile/generic.xml ]] || \
 199     ln -s generic_limited_net.xml $ALTROOT/etc/svc/profile/generic.xml
 200   [[ -L $ALTROOT/etc/svc/profile/name_service.xml ]] || \
 201     ln -s ns_dns.xml $ALTROOT/etc/svc/profile/name_service.xml
 202   return 0
 203 }
 204 
 205 Postboot() {
 206   [[ -f $ALTROOT/.initialboot ]] || touch $ALTROOT/.initialboot
 207   echo "$*" >> $ALTROOT/.initialboot
 208 }
 209 
 210 Reboot() {
 211   # This is an awful hack... we already setup bootadm
 212   # and we've likely deleted enough of the userspace that this
 213   # can't run successfully... The easiest way to skip it is to
 214   # remove the binary
 215   rm -f /sbin/bootadm
 216   svccfg -s "system/boot-config:default" setprop config/fastreboot_default=false
 217   svcadm refresh svc:/system/boot-config:default
 218   reboot
 219 }
 220 
 221 RunInstall(){
 222   FetchConfig || bomb "Could not fecth kayak config for target"
 223   . $ICFILE
 224   Postboot 'exit $SMF_EXIT_OK'
 225   ApplyChanges || bomb "Could not apply all configuration changes"
 226   MakeBootable || bomb "Could not make new BE bootable"
 227   log "Install complete"
 228   return 0
 229 }