Print this page
Modernize CDDL license text and copyrights for OmniTI-original code.
Factor out SetKeyboardLayout so a PXE server-side config can call it out.
Fix PXE regressions.
Do better on keyboard selection, plus save it in installed image.
Also, pv(1) output for install doesn't scroll anymore.
Kayak for ISO checkpoint 1
Initial foray into Kayak for ISO
   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(){


  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 }
   1 #!/usr/bin/bash
   2 
   3 #
   4 # This file and its contents are supplied under the terms of the
   5 # Common Development and Distribution License ("CDDL"), version 1.0.
   6 # You may only use this file in accordance with the terms of version
   7 # 1.0 of the CDDL.
   8 #
   9 # A full copy of the text of the CDDL should have accompanied this
  10 # source.  A copy of the CDDL is also available via the Internet at
  11 # http://www.illumos.org/license/CDDL.

  12 #
  13 



  14 #
  15 # Copyright 2017 OmniTI Computer Consulting, Inc.  All rights reserved.




  16 #
  17 





  18 LOG_SETUP=0
  19 
  20 ConsoleLog(){
  21   exec 4>/dev/console
  22   exec 1>>${1}
  23   exec 2>>${1}
  24   INSTALL_LOG=${1}
  25   LOG_SETUP=1
  26 }
  27 CopyInstallLog(){
  28   if [[ -n "$INSTALL_LOG" ]]; then
  29     cp $INSTALL_LOG $ALTROOT/var/log/install/kayak.log
  30   fi
  31 }
  32 SendInstallLog(){
  33   PUTURL=`echo $CONFIG | sed -e 's%/kayak/%/kayaklog/%g;'`
  34   PUTURL=`echo $PUTURL | sed -e 's%/kayak$%/kayaklog%g;'`
  35   curl -T $INSTALL_LOG $PUTURL/$ETHER
  36 }
  37 OutputLog(){


  74 SetRootPW(){
  75   sed -i -e 's%^root::%root:'$ROOTPW':%' $ALTROOT/etc/shadow
  76 }
  77 ForceDHCP(){
  78   log "Forcing all interfaces into DHCP..."
  79   /sbin/ifconfig -a plumb 2> /dev/null
  80   # for the logs
  81   for iface in `/sbin/dladm show-phys -o device -p` ; do
  82     /sbin/ifconfig $iface dhcp &
  83   done
  84   while [[ -z $(/sbin/dhcpinfo BootSrvA) ]]; do
  85     log "Waiting for dhcpinfo..."
  86     sleep 1
  87   done
  88   BOOTSRVA=`/sbin/dhcpinfo BootSrvA`
  89   log "Next server: $BOOTSRVA"
  90   sleep 1
  91 }
  92 
  93 BuildBE() {
  94   RPOOL=${1:-rpool}
  95   if [[ -z $2 ]]; then
  96       BOOTSRVA=`/sbin/dhcpinfo BootSrvA`
  97       MEDIA=`getvar install_media`
  98       MEDIA=`echo $MEDIA | sed -e "s%//\:%//$BOOTSRVA\:%g;"`
  99       MEDIA=`echo $MEDIA | sed -e "s%///%//$BOOTSRVA/%g;"`
 100       DECOMP="bzip2 -dc"
 101       GRAB="curl -s"
 102   else
 103       # ASSUME $2 is a file path.  TODO: Parse the URL...
 104       MEDIA=$2
 105       # TODO: make switch statement based on $MEDIA's extension.
 106       # e.g. "bz2" ==> "bzip -dc", "7z" ==> 
 107       DECOMP="bzip2 -dc"
 108       GRAB=cat
 109   fi
 110   zfs set compression=on $RPOOL
 111   zfs create $RPOOL/ROOT
 112   zfs set canmount=off $RPOOL/ROOT
 113   zfs set mountpoint=legacy $RPOOL/ROOT
 114   log "Receiving image: $MEDIA"
 115   $GRAB $MEDIA | pv -B 128m -w 78 | $DECOMP | zfs receive -u $RPOOL/ROOT/omnios
 116   zfs set canmount=noauto $RPOOL/ROOT/omnios
 117   zfs set mountpoint=legacy $RPOOL/ROOT/omnios
 118   log "Cleaning up boot environment"
 119   beadm mount omnios /mnt
 120   ALTROOT=/mnt
 121   cp $ALTROOT/lib/svc/seed/global.db $ALTROOT/etc/svc/repository.db
 122   chmod 0600 $ALTROOT/etc/svc/repository.db
 123   chown root:sys $ALTROOT/etc/svc/repository.db
 124   /usr/sbin/devfsadm -r /mnt
 125   [[ -L $ALTROOT/dev/msglog ]] || \
 126     ln -s ../devices/pseudo/sysmsg@0:msglog $ALTROOT/dev/msglog
 127   MakeSwapDump
 128   zfs destroy $RPOOL/ROOT/omnios@kayak
 129 }
 130 
 131 FetchConfig(){
 132   ETHER=`Ether`
 133   BOOTSRVA=`/sbin/dhcpinfo BootSrvA`
 134   CONFIG=`getvar install_config`
 135   CONFIG=`echo $CONFIG | sed -e "s%//\:%//$BOOTSRVA\:%g;"`
 136   CONFIG=`echo $CONFIG | sed -e "s%///%//$BOOTSRVA/%g;"`
 137   L=${#ETHER}
 138   while [[ "$L" -gt "0" ]]; do
 139     URL="$CONFIG/${ETHER:0:$L}"
 140     log "... trying $URL"
 141     /bin/curl -s -o $ICFILE $URL
 142     if [[ -f $ICFILE ]]; then
 143       if [[ -n $(grep BuildRpool $ICFILE) ]]; then
 144         log "fetched config."
 145         return 0
 146       fi
 147       rm -f $ICFILE
 148     fi
 149     L=$(($L - 1))
 150   done
 151   return 1
 152 }
 153 
 154 MakeBootable(){
 155   RPOOL=${1:-rpool}
 156   log "Making boot environment bootable"
 157   zpool set bootfs=$RPOOL/ROOT/omnios rpool
 158   # Must do beadm activate first on the off chance we're bootstrapping from
 159   # GRUB.
 160   beadm activate omnios || return 1
 161 
 162   if [[ ! -z $1 ]]; then
 163       # Generate kayak-disk-list from zpool status.
 164       # NOTE: If this is something on non-s0 slices, the installboot below
 165       # will fail most likely, which is possibly a desired result.
 166       zpool list -v $RPOOL | egrep -v "NAME|rpool|mirror" | \
 167           awk '{print $1}' | sed -E 's/s0$//g' > /tmp/kayak-disk-list
 168   fi
 169 
 170   # NOTE:  This installboot loop assumes we're doing GPT whole-disk rpools.
 171   for i in `cat /tmp/kayak-disk-list`
 172   do
 173       installboot -mfF /boot/pmbr /boot/gptzfsboot /dev/rdsk/${i}s0 || return 1
 174   done
 175 
 176   bootadm update-archive -R $ALTROOT || return 1
 177   return 0
 178 }
 179 
 180 SetHostname()
 181 {
 182   log "Setting hostname: ${1}"
 183   /bin/hostname "$1"
 184   echo "$1" > $ALTROOT/etc/nodename
 185   head -n 26 $ALTROOT/etc/hosts > /tmp/hosts
 186   echo "::1\t\t$1" >> /tmp/hosts
 187   echo "127.0.0.1\t$1" >> /tmp/hosts
 188   cat /tmp/hosts > $ALTROOT/etc/hosts
 189 }
 190 
 191 AutoHostname() {
 192   suffix=$1
 193   macadr=`/sbin/ifconfig -a | \
 194           /usr/bin/awk '/UP/{if($2 !~ /LOOPBACK/){iface=$1;}} /ether/{if(iface){print $2; exit;}}' | \
 195           /bin/tr '[:upper:]' '[:lower:]' | \
 196           /bin/sed -e 's/^/ 0/g;s/:/-0/g; s/0\([0-9a-f][0-9a-f]\)/\1/g; s/ //g;'`
 197   [ -z $suffix ] && suffix=omnios
 198   [ "$suffix" == "-" ] && suffix= || suffix=-$suffix
 199   SetHostname $macadr$suffix
 200 }
 201 
 202 SetTimezone()
 203 {
 204   log "Setting timezone: ${1}"
 205   sed -i -e "s:^TZ=.*:TZ=${1}:" $ALTROOT/etc/default/init
 206 }
 207 
 208 SetLang()
 209 {
 210   log "Setting language: ${1}"
 211   sed -i -e "s:^LANG=.*:LANG=${1}:" $ALTROOT/etc/default/init
 212 }
 213 
 214 SetKeyboardLayout()
 215 {
 216       # Put the new keyboard layout ($1) in
 217       # "setprop keyboard-layout <foo>" in the newly-installed root's
 218       # /boot/solaris/bootenv.rc (aka. eeprom(1M) storage for amd64/i386).
 219       layout=$1
 220       sed "s/keyboard-layout Unknown/keyboard-layout $layout/g" \
 221           < $ALTROOT/boot/solaris/bootenv.rc > /tmp/bootenv.rc
 222       mv /tmp/bootenv.rc $ALTROOT/boot/solaris/bootenv.rc
 223       # Also modify the SMF manifest, assuming US-English was set by default.
 224       sed "s/US-English/$layout/g" \
 225          < $ALTROOT/lib/svc/manifest/system/keymap.xml > /tmp/keymap.xml
 226       cp -f /tmp/keymap.xml $ALTROOT/lib/svc/manifest/system/keymap.xml
 227 }
 228 
 229 ApplyChanges(){
 230   SetRootPW
 231   [[ -L $ALTROOT/etc/svc/profile/generic.xml ]] || \
 232     ln -s generic_limited_net.xml $ALTROOT/etc/svc/profile/generic.xml
 233   [[ -L $ALTROOT/etc/svc/profile/name_service.xml ]] || \
 234     ln -s ns_dns.xml $ALTROOT/etc/svc/profile/name_service.xml
 235 
 236   # Extras from interactive ISO/USB install...
 237   # arg1 == hostname
 238   if [[ ! -z $1 ]]; then
 239       SetHostname $1
 240   fi
 241 
 242   # arg2 == timezone
 243   if [[ ! -z $2 ]]; then
 244       SetTimezone $2
 245   fi
 246 
 247   # arg3 == Language
 248   if [[ ! -z $3 ]]; then
 249       SetLang $3
 250   fi
 251 
 252   # arg4 == Keyboard layout
 253   if [[ ! -z $4 ]]; then
 254       SetKeyboardLayout $4
 255   fi
 256 
 257   return 0
 258 }
 259 
 260 Postboot() {
 261   [[ -f $ALTROOT/.initialboot ]] || touch $ALTROOT/.initialboot
 262   echo "$*" >> $ALTROOT/.initialboot
 263 }
 264 
 265 Reboot() {
 266   # This is an awful hack... we already setup bootadm
 267   # and we've likely deleted enough of the userspace that this
 268   # can't run successfully... The easiest way to skip it is to
 269   # remove the binary
 270   rm -f /sbin/bootadm
 271   svccfg -s "system/boot-config:default" setprop config/fastreboot_default=false
 272   svcadm refresh svc:/system/boot-config:default
 273   reboot
 274 }
 275 
 276 RunInstall(){
 277   FetchConfig || bomb "Could not fetch kayak config for target"
 278   # Set RPOOL if it wasn't done so already. We need it set.
 279   RPOOL=${RPOOL:-rpool}
 280   . $ICFILE
 281   Postboot 'exit $SMF_EXIT_OK'
 282   ApplyChanges || bomb "Could not apply all configuration changes"
 283   MakeBootable || bomb "Could not make new BE bootable"
 284   log "Install complete"
 285   return 0
 286 }