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 }