functions-extractimage.sh revision 225657
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 225657 2011-09-19 05:12:53Z jpaetzel $ 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 if ! kldstat -v | grep -q "geom_uzip" ; then 59 exit_err "Kernel module geom_uzip not loaded" 60 fi 61 62 # Start by mounting the uzip image 63 MDDEVICE=`mdconfig -a -t vnode -o readonly -f ${INSFILE}` 64 mkdir -p ${FSMNT}.uzip 65 mount -r /dev/${MDDEVICE}.uzip ${FSMNT}.uzip 66 if [ $? -ne 0 ] 67 then 68 exit_err "ERROR: Failed mounting the ${INSFILE}" 69 fi 70 cd ${FSMNT}.uzip 71 72 # Copy over all the files now! 73 tar cvf - . 2>/dev/null | tar -xpv -C ${FSMNT} ${TAROPTS} -f - 2>&1 | tee -a ${FSMNT}/.tar-extract.log 74 if [ $? -ne 0 ] 75 then 76 cd / 77 echo "TAR failure occurred:" >>${LOGOUT} 78 cat ${FSMNT}/.tar-extract.log | grep "tar:" >>${LOGOUT} 79 umount ${FSMNT}.uzip 80 mdconfig -d -u ${MDDEVICE} 81 exit_err "ERROR: Failed extracting the tar image" 82 fi 83 84 # All finished, now lets umount and cleanup 85 cd / 86 umount ${FSMNT}.uzip 87 mdconfig -d -u ${MDDEVICE} 88 ;; 89 tar) 90 tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1 91 if [ $? -ne 0 ] 92 then 93 exit_err "ERROR: Failed extracting the tar image" 94 fi 95 ;; 96 esac 97 98 # Check if this was a FTP download and clean it up now 99 if [ "${INSTALLMEDIUM}" = "ftp" ] 100 then 101 echo_log "Cleaning up downloaded archive" 102 rm ${INSFILE} 103 rm ${INSFILE}.count >/dev/null 2>/dev/null 104 rm ${INSFILE}.md5 >/dev/null 2>/dev/null 105 fi 106 107 echo_log "pc-sysinstall: Extraction Finished" 108 109}; 110 111# Performs the extraction of data to disk from a directory with split files 112start_extract_split() 113{ 114 if [ -z "${INSDIR}" ] 115 then 116 exit_err "ERROR: Called extraction with no install directory set!" 117 fi 118 119 echo_log "pc-sysinstall: Starting Extraction" 120 121 # Used by install.sh 122 DESTDIR="${FSMNT}" 123 export DESTDIR 124 125 HERE=`pwd` 126 DIRS=`ls -d ${INSDIR}/*|grep -Ev '(uzip|kernels|src)'` 127 for dir in ${DIRS} 128 do 129 cd "${dir}" 130 if [ -f "install.sh" ] 131 then 132 echo_log "Extracting" `basename ${dir}` 133 echo "y" | sh install.sh >/dev/null 134 if [ $? -ne 0 ] 135 then 136 exit_err "ERROR: Failed extracting ${dir}" 137 fi 138 else 139 exit_err "ERROR: ${dir}/install.sh does not exist" 140 fi 141 done 142 cd "${HERE}" 143 144 KERNELS=`ls -d ${INSDIR}/*|grep kernels` 145 cd "${KERNELS}" 146 if [ -f "install.sh" ] 147 then 148 echo_log "Extracting" `basename ${KERNELS}` 149 echo "y" | sh install.sh generic >/dev/null 150 if [ $? -ne 0 ] 151 then 152 exit_err "ERROR: Failed extracting ${KERNELS}" 153 fi 154 rm -rf "${FSMNT}/boot/kernel" 155 mv "${FSMNT}/boot/GENERIC" "${FSMNT}/boot/kernel" 156 else 157 exit_err "ERROR: ${KERNELS}/install.sh does not exist" 158 fi 159 cd "${HERE}" 160 161 SOURCE=`ls -d ${INSDIR}/*|grep src` 162 cd "${SOURCE}" 163 if [ -f "install.sh" ] 164 then 165 echo_log "Extracting" `basename ${SOURCE}` 166 echo "y" | sh install.sh all >/dev/null 167 if [ $? -ne 0 ] 168 then 169 exit_err "ERROR: Failed extracting ${SOURCE}" 170 fi 171 else 172 exit_err "ERROR: ${SOURCE}/install.sh does not exist" 173 fi 174 cd "${HERE}" 175 176 echo_log "pc-sysinstall: Extraction Finished" 177}; 178 179# Function which will attempt to fetch the install file before we start 180# the install 181fetch_install_file() 182{ 183 get_value_from_cfg ftpPath 184 if [ -z "$VAL" ] 185 then 186 exit_err "ERROR: Install medium was set to ftp, but no ftpPath was provided!" 187 fi 188 189 FTPPATH="${VAL}" 190 191 # Check if we have a /usr partition to save the download 192 if [ -d "${FSMNT}/usr" ] 193 then 194 OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}" 195 else 196 OUTFILE="${FSMNT}/.fetch-${INSFILE}" 197 fi 198 199 # Do the fetch of the archive now 200 fetch_file "${FTPPATH}/${INSFILE}" "${OUTFILE}" "1" 201 202 # Check to see if there is a .count file for this install 203 fetch_file "${FTPPATH}/${INSFILE}.count" "${OUTFILE}.count" "0" 204 205 # Check to see if there is a .md5 file for this install 206 fetch_file "${FTPPATH}/${INSFILE}.md5" "${OUTFILE}.md5" "0" 207 208 # Done fetching, now reset the INSFILE to our downloaded archived 209 export INSFILE="${OUTFILE}" 210 211}; 212 213# Function which will download freebsd install files 214fetch_split_files() 215{ 216 get_ftpHost 217 if [ -z "$VAL" ] 218 then 219 exit_err "ERROR: Install medium was set to ftp, but no ftpHost was provided!" 220 fi 221 FTPHOST="${VAL}" 222 223 get_ftpDir 224 if [ -z "$VAL" ] 225 then 226 exit_err "ERROR: Install medium was set to ftp, but no ftpDir was provided!" 227 fi 228 FTPDIR="${VAL}" 229 230 # Check if we have a /usr partition to save the download 231 if [ -d "${FSMNT}/usr" ] 232 then 233 OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}" 234 else 235 OUTFILE="${FSMNT}/.fetch-${INSFILE}" 236 fi 237 238 DIRS="base catpages dict doc games info manpages proflibs kernels src" 239 if [ "${FBSD_ARCH}" = "amd64" ] 240 then 241 DIRS="${DIRS} lib32" 242 fi 243 244 for d in ${DIRS} 245 do 246 mkdir -p "${OUTFILE}/${d}" 247 done 248 249 250 NETRC="${OUTFILE}/.netrc" 251 cat <<EOF >"${NETRC}" 252machine ${FTPHOST} 253login anonymous 254password anonymous 255macdef INSTALL 256bin 257prompt 258EOF 259 260 for d in ${DIRS} 261 do 262 cat <<EOF >>"${NETRC}" 263cd ${FTPDIR}/${d} 264lcd ${OUTFILE}/${d} 265mreget * 266EOF 267 done 268 269 cat <<EOF >>"${NETRC}" 270bye 271 272 273EOF 274 275 # Fetch the files via ftp 276 echo "$ INSTALL" | ftp -N "${NETRC}" "${FTPHOST}" 277 278 # Done fetching, now reset the INSFILE to our downloaded archived 279 export INSFILE="${OUTFILE}" 280} 281 282# Function which does the rsync download from the server specified in cfg 283start_rsync_copy() 284{ 285 # Load our rsync config values 286 get_value_from_cfg rsyncPath 287 if [ -z "${VAL}" ]; then 288 exit_err "ERROR: rsyncPath is unset! Please check your config and try again." 289 fi 290 export RSYNCPATH="${VAL}" 291 292 get_value_from_cfg rsyncHost 293 if [ -z "${VAL}" ]; then 294 exit_err "ERROR: rsyncHost is unset! Please check your config and try again." 295 fi 296 export RSYNCHOST="${VAL}" 297 298 get_value_from_cfg rsyncUser 299 if [ -z "${VAL}" ]; then 300 exit_err "ERROR: rsyncUser is unset! Please check your config and try again." 301 fi 302 export RSYNCUSER="${VAL}" 303 304 get_value_from_cfg rsyncPort 305 if [ -z "${VAL}" ]; then 306 exit_err "ERROR: rsyncPort is unset! Please check your config and try again." 307 fi 308 export RSYNCPORT="${VAL}" 309 310 COUNT=1 311 while 312 z=1 313 do 314 if [ ${COUNT} -gt ${RSYNCTRIES} ] 315 then 316 exit_err "ERROR: Failed rsync command!" 317 break 318 fi 319 320 rsync -avvzHsR \ 321 --rsync-path="rsync --fake-super" \ 322 -e "ssh -p ${RSYNCPORT}" \ 323 ${RSYNCUSER}@${RSYNCHOST}:${RSYNCPATH}/./ ${FSMNT} 324 if [ $? -ne 0 ] 325 then 326 echo "Rsync failed! Tries: ${COUNT}" 327 else 328 break 329 fi 330 331 COUNT=$((COUNT+1)) 332 done 333 334}; 335 336start_image_install() 337{ 338 if [ -z "${IMAGE_FILE}" ] 339 then 340 exit_err "ERROR: installMedium set to image but no image file specified!" 341 fi 342 343 # We are ready to start mounting, lets read the config and do it 344 while read line 345 do 346 echo $line | grep -q "^disk0=" 2>/dev/null 347 if [ $? -eq 0 ] 348 then 349 # Found a disk= entry, lets get the disk we are working on 350 get_value_from_string "${line}" 351 strip_white_space "$VAL" 352 DISK="$VAL" 353 fi 354 355 echo $line | grep -q "^commitDiskPart" 2>/dev/null 356 if [ $? -eq 0 ] 357 then 358 # Found our flag to commit this disk setup / lets do sanity check and do it 359 if [ -n "${DISK}" ] 360 then 361 362 # Write the image 363 write_image "${IMAGE_FILE}" "${DISK}" 364 365 # Increment our disk counter to look for next disk and unset 366 unset DISK 367 break 368 369 else 370 exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!" 371 fi 372 fi 373 374 done <${CFGF} 375}; 376 377# Entrance function, which starts the installation process 378init_extraction() 379{ 380 # Figure out what file we are using to install from via the config 381 get_value_from_cfg installFile 382 383 if [ -n "${VAL}" ] 384 then 385 export INSFILE="${VAL}" 386 else 387 # If no installFile specified, try our defaults 388 if [ "$INSTALLTYPE" = "FreeBSD" ] 389 then 390 case $PACKAGETYPE in 391 uzip) INSFILE="${FBSD_UZIP_FILE}" ;; 392 tar) INSFILE="${FBSD_TAR_FILE}" ;; 393 split) 394 INSDIR="${FBSD_BRANCH_DIR}" 395 396 # This is to trick opt_mount into not failing 397 INSFILE="${INSDIR}" 398 ;; 399 esac 400 else 401 case $PACKAGETYPE in 402 uzip) INSFILE="${UZIP_FILE}" ;; 403 tar) INSFILE="${TAR_FILE}" ;; 404 esac 405 fi 406 export INSFILE 407 fi 408 409 # Lets start by figuring out what medium we are using 410 case ${INSTALLMEDIUM} in 411 dvd|usb) 412 # Lets start by mounting the disk 413 opt_mount 414 if [ -n "${INSDIR}" ] 415 then 416 INSDIR="${CDMNT}/${INSDIR}" ; export INSDIR 417 start_extract_split 418 419 else 420 INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE 421 start_extract_uzip_tar 422 fi 423 ;; 424 425 ftp) 426 if [ "$PACKAGETYPE" = "split" ] 427 then 428 fetch_split_files 429 430 INSDIR="${INSFILE}" ; export INSDIR 431 start_extract_split 432 else 433 fetch_install_file 434 start_extract_uzip_tar 435 fi 436 ;; 437 438 sftp) ;; 439 440 rsync) start_rsync_copy ;; 441 image) start_image_install ;; 442 local) 443 get_value_from_cfg localPath 444 if [ -z "$VAL" ] 445 then 446 exit_err "Install medium was set to local, but no localPath was provided!" 447 fi 448 LOCALPATH=$VAL 449 INSFILE="${LOCALPATH}/${INSFILE}" ; export INSFILE 450 start_extract_uzip_tar 451 ;; 452 *) exit_err "ERROR: Unknown install medium" ;; 453 esac 454 455}; 456