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 }
 |