functions-extractimage.sh revision 214189
1#!/bin/sh 2#- 3# Copyright (c) 2010 iXsystems, Inc. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24# SUCH DAMAGE. 25# 26# $FreeBSD: head/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh 214189 2010-10-21 23:08:42Z imp $ 27 28# Functions which perform the extraction / installation of system to disk 29 30. ${BACKEND}/functions-mountoptical.sh 31 32# Performs the extraction of data to disk from a uzip or tar archive 33start_extract_uzip_tar() 34{ 35 if [ -z "$INSFILE" ] 36 then 37 exit_err "ERROR: Called extraction with no install file set!" 38 fi 39 40 # Check if we have a .count file, and echo it out for a front-end to use in progress bars 41 if [ -e "${INSFILE}.count" ] 42 then 43 echo "INSTALLCOUNT: `cat ${INSFILE}.count`" 44 fi 45 46 # Check if we are doing an upgrade, and if so use our exclude list 47 if [ "${INSTALLMODE}" = "upgrade" ] 48 then 49 TAROPTS="-X ${PROGDIR}/conf/exclude-from-upgrade" 50 else 51 TAROPTS="" 52 fi 53 54 echo_log "pc-sysinstall: Starting Extraction" 55 56 case ${PACKAGETYPE} in 57 uzip) 58 # Start by mounting the uzip image 59 MDDEVICE=`mdconfig -a -t vnode -o readonly -f ${INSFILE}` 60 mkdir -p ${FSMNT}.uzip 61 mount -r /dev/${MDDEVICE}.uzip ${FSMNT}.uzip 62 if [ "$?" != "0" ] 63 then 64 exit_err "ERROR: Failed mounting the ${INSFILE}" 65 fi 66 cd ${FSMNT}.uzip 67 68 # Copy over all the files now! 69 tar cvf - . 2>/dev/null | tar -xpv -C ${FSMNT} ${TAROPTS} -f - 2>&1 | tee -a ${FSMNT}/.tar-extract.log 70 if [ "$?" != "0" ] 71 then 72 cd / 73 echo "TAR failure occurred:" >>${LOGOUT} 74 cat ${FSMNT}/.tar-extract.log | grep "tar:" >>${LOGOUT} 75 umount ${FSMNT}.uzip 76 mdconfig -d -u ${MDDEVICE} 77 exit_err "ERROR: Failed extracting the tar image" 78 fi 79 80 # All finished, now lets umount and cleanup 81 cd / 82 umount ${FSMNT}.uzip 83 mdconfig -d -u ${MDDEVICE} 84 ;; 85 tar) 86 tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1 87 if [ "$?" != "0" ] 88 then 89 exit_err "ERROR: Failed extracting the tar image" 90 fi 91 ;; 92 esac 93 94 # Check if this was a FTP download and clean it up now 95 if [ "${INSTALLMEDIUM}" = "ftp" ] 96 then 97 echo_log "Cleaning up downloaded archive" 98 rm ${INSFILE} 99 rm ${INSFILE}.count >/dev/null 2>/dev/null 100 rm ${INSFILE}.md5 >/dev/null 2>/dev/null 101 fi 102 103 echo_log "pc-sysinstall: Extraction Finished" 104 105}; 106 107# Performs the extraction of data to disk from a directory with split files 108start_extract_split() 109{ 110 if [ -z "${INSDIR}" ] 111 then 112 exit_err "ERROR: Called extraction with no install directory set!" 113 fi 114 115 echo_log "pc-sysinstall: Starting Extraction" 116 117 # Used by install.sh 118 DESTDIR="${FSMNT}" 119 export DESTDIR 120 121 HERE=`pwd` 122 DIRS=`ls -d ${INSDIR}/*|grep -Ev '(uzip|kernels|src)'` 123 for dir in ${DIRS} 124 do 125 cd "${dir}" 126 if [ -f "install.sh" ] 127 then 128 echo_log "Extracting" `basename ${dir}` 129 echo "y" | sh install.sh >/dev/null 130 if [ "$?" != "0" ] 131 then 132 exit_err "ERROR: Failed extracting ${dir}" 133 fi 134 else 135 exit_err "ERROR: ${dir}/install.sh does not exist" 136 fi 137 done 138 cd "${HERE}" 139 140 KERNELS=`ls -d ${INSDIR}/*|grep kernels` 141 cd "${KERNELS}" 142 if [ -f "install.sh" ] 143 then 144 echo_log "Extracting" `basename ${KERNELS}` 145 echo "y" | sh install.sh generic >/dev/null 146 if [ "$?" != "0" ] 147 then 148 exit_err "ERROR: Failed extracting ${KERNELS}" 149 fi 150 rm -rf "${FSMNT}/boot/kernel" 151 mv "${FSMNT}/boot/GENERIC" "${FSMNT}/boot/kernel" 152 else 153 exit_err "ERROR: ${KERNELS}/install.sh does not exist" 154 fi 155 cd "${HERE}" 156 157 SOURCE=`ls -d ${INSDIR}/*|grep src` 158 cd "${SOURCE}" 159 if [ -f "install.sh" ] 160 then 161 echo_log "Extracting" `basename ${SOURCE}` 162 echo "y" | sh install.sh all >/dev/null 163 if [ "$?" != "0" ] 164 then 165 exit_err "ERROR: Failed extracting ${SOURCE}" 166 fi 167 else 168 exit_err "ERROR: ${SOURCE}/install.sh does not exist" 169 fi 170 cd "${HERE}" 171 172 echo_log "pc-sysinstall: Extraction Finished" 173}; 174 175# Function which will attempt to fetch the install file before we start 176# the install 177fetch_install_file() 178{ 179 get_value_from_cfg ftpPath 180 if [ -z "$VAL" ] 181 then 182 exit_err "ERROR: Install medium was set to ftp, but no ftpPath was provided!" 183 fi 184 185 FTPPATH="${VAL}" 186 187 # Check if we have a /usr partition to save the download 188 if [ -d "${FSMNT}/usr" ] 189 then 190 OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}" 191 else 192 OUTFILE="${FSMNT}/.fetch-${INSFILE}" 193 fi 194 195 # Do the fetch of the archive now 196 fetch_file "${FTPPATH}/${INSFILE}" "${OUTFILE}" "1" 197 198 # Check to see if there is a .count file for this install 199 fetch_file "${FTPPATH}/${INSFILE}.count" "${OUTFILE}.count" "0" 200 201 # Check to see if there is a .md5 file for this install 202 fetch_file "${FTPPATH}/${INSFILE}.md5" "${OUTFILE}.md5" "0" 203 204 # Done fetching, now reset the INSFILE to our downloaded archived 205 INSFILE="${OUTFILE}" ; export INSFILE 206 207}; 208 209# Function which will download freebsd install files 210fetch_split_files() 211{ 212 get_ftpHost 213 if [ -z "$VAL" ] 214 then 215 exit_err "ERROR: Install medium was set to ftp, but no ftpHost was provided!" 216 fi 217 FTPHOST="${VAL}" 218 219 get_ftpDir 220 if [ -z "$VAL" ] 221 then 222 exit_err "ERROR: Install medium was set to ftp, but no ftpDir was provided!" 223 fi 224 FTPDIR="${VAL}" 225 226 # Check if we have a /usr partition to save the download 227 if [ -d "${FSMNT}/usr" ] 228 then 229 OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}" 230 else 231 OUTFILE="${FSMNT}/.fetch-${INSFILE}" 232 fi 233 234 DIRS="base catpages dict doc games info manpages proflibs kernels src" 235 if [ "${FBSD_ARCH}" = "amd64" ] 236 then 237 DIRS="${DIRS} lib32" 238 fi 239 240 for d in ${DIRS} 241 do 242 mkdir -p "${OUTFILE}/${d}" 243 done 244 245 246 NETRC="${OUTFILE}/.netrc" 247 cat<<EOF>"${NETRC}" 248machine ${FTPHOST} 249login anonymous 250password anonymous 251macdef INSTALL 252bin 253prompt 254EOF 255 256 for d in ${DIRS} 257 do 258 cat<<EOF>>"${NETRC}" 259cd ${FTPDIR}/${d} 260lcd ${OUTFILE}/${d} 261mreget * 262EOF 263 done 264 265 cat<<EOF>>"${NETRC}" 266bye 267 268 269EOF 270 271 # Fetch the files via ftp 272 echo "$ INSTALL" | ftp -N "${NETRC}" "${FTPHOST}" 273 274 # Done fetching, now reset the INSFILE to our downloaded archived 275 INSFILE="${OUTFILE}" ; export INSFILE 276} 277 278# Function which does the rsync download from the server specified in cfg 279start_rsync_copy() 280{ 281 # Load our rsync config values 282 get_value_from_cfg rsyncPath 283 if [ -z "${VAL}" ]; then 284 exit_err "ERROR: rsyncPath is unset! Please check your config and try again." 285 fi 286 RSYNCPATH="${VAL}" ; export RSYNCPATH 287 288 get_value_from_cfg rsyncHost 289 if [ -z "${VAL}" ]; then 290 exit_err "ERROR: rsyncHost is unset! Please check your config and try again." 291 fi 292 RSYNCHOST="${VAL}" ; export RSYNCHOST 293 294 get_value_from_cfg rsyncUser 295 if [ -z "${VAL}" ]; then 296 exit_err "ERROR: rsyncUser is unset! Please check your config and try again." 297 fi 298 RSYNCUSER="${VAL}" ; export RSYNCUSER 299 300 get_value_from_cfg rsyncPort 301 if [ -z "${VAL}" ]; then 302 exit_err "ERROR: rsyncPort is unset! Please check your config and try again." 303 fi 304 RSYNCPORT="${VAL}" ; export RSYNCPORT 305 306 COUNT="1" 307 while 308 z=1 309 do 310 if [ ${COUNT} -gt ${RSYNCTRIES} ] 311 then 312 exit_err "ERROR: Failed rsync command!" 313 break 314 fi 315 316 rsync -avvzHsR \ 317 --rsync-path="rsync --fake-super" \ 318 -e "ssh -p ${RSYNCPORT}" \ 319 ${RSYNCUSER}@${RSYNCHOST}:${RSYNCPATH}/./ ${FSMNT} 320 if [ "$?" != "0" ] 321 then 322 echo "Rsync failed! Tries: ${COUNT}" 323 else 324 break 325 fi 326 327 COUNT="`expr ${COUNT} + 1`" 328 done 329 330}; 331 332start_image_install() 333{ 334 if [ -z "${IMAGE_FILE}" ] 335 then 336 exit_err "ERROR: installMedium set to image but no image file specified!" 337 fi 338 339 # We are ready to start mounting, lets read the config and do it 340 while read line 341 do 342 echo $line | grep "^disk0=" >/dev/null 2>/dev/null 343 if [ "$?" = "0" ] 344 then 345 # Found a disk= entry, lets get the disk we are working on 346 get_value_from_string "${line}" 347 strip_white_space "$VAL" 348 DISK="$VAL" 349 fi 350 351 echo $line | grep "^commitDiskPart" >/dev/null 2>/dev/null 352 if [ "$?" = "0" ] 353 then 354 # Found our flag to commit this disk setup / lets do sanity check and do it 355 if [ ! -z "${DISK}" ] 356 then 357 358 # Write the image 359 write_image "${IMAGE_FILE}" "${DISK}" 360 361 # Increment our disk counter to look for next disk and unset 362 unset DISK 363 break 364 365 else 366 exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!" 367 fi 368 fi 369 370 done <${CFGF} 371}; 372 373# Entrance function, which starts the installation process 374init_extraction() 375{ 376 # Figure out what file we are using to install from via the config 377 get_value_from_cfg installFile 378 379 if [ ! -z "${VAL}" ] 380 then 381 INSFILE="${VAL}" ; export INSFILE 382 else 383 # If no installFile specified, try our defaults 384 if [ "$INSTALLTYPE" = "FreeBSD" ] 385 then 386 case $PACKAGETYPE in 387 uzip) INSFILE="${FBSD_UZIP_FILE}" ;; 388 tar) INSFILE="${FBSD_TAR_FILE}" ;; 389 split) 390 INSDIR="${FBSD_BRANCH_DIR}" 391 392 # This is to trick opt_mount into not failing 393 INSFILE="${INSDIR}" 394 ;; 395 esac 396 else 397 case $PACKAGETYPE in 398 uzip) INSFILE="${UZIP_FILE}" ;; 399 tar) INSFILE="${TAR_FILE}" ;; 400 esac 401 fi 402 export INSFILE 403 fi 404 405 # Lets start by figuring out what medium we are using 406 case ${INSTALLMEDIUM} in 407 dvd|usb) 408 # Lets start by mounting the disk 409 opt_mount 410 if [ ! -z "${INSDIR}" ] 411 then 412 INSDIR="${CDMNT}/${INSDIR}" ; export INSDIR 413 start_extract_split 414 415 else 416 INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE 417 start_extract_uzip_tar 418 fi 419 ;; 420 421 ftp) 422 if [ "$PACKAGETYPE" = "split" ] 423 then 424 fetch_split_files 425 426 INSDIR="${INSFILE}" ; export INSDIR 427 start_extract_split 428 else 429 fetch_install_file 430 start_extract_uzip_tar 431 fi 432 ;; 433 434 sftp) ;; 435 436 rsync) start_rsync_copy ;; 437 image) start_image_install ;; 438 *) exit_err "ERROR: Unknown install medium" ;; 439 esac 440 441}; 442