3 # Copyright (c) 2010 iXsystems, Inc. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
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.
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
28 # Functions which perform the extraction / installation of system to disk
30 . ${BACKEND}/functions-mountoptical.sh
32 # Performs the extraction of data to disk from FreeBSD dist files
35 if [ -z "$1" ] ; then exit_err "Called dist extraction with no directory set!"; fi
36 if [ -z "$INSFILE" ]; then exit_err "Called extraction with no install file set!"; fi
39 # Check if we are doing an upgrade, and if so use our exclude list
40 if [ "${INSTALLMODE}" = "upgrade" ]; then
41 TAROPTS="-X ${PROGDIR}/conf/exclude-from-upgrade"
46 # Loop though and extract dist files
49 # Check the MANIFEST see if we have an archive size / count
50 if [ -e "${DDIR}/MANIFEST" ]; then
51 count=`grep "^${di}.txz" ${DDIR}/MANIFEST | awk '{print $3}'`
52 if [ ! -z "$count" ] ; then
53 echo "INSTALLCOUNT: $count"
56 echo_log "pc-sysinstall: Starting Extraction (${di})"
57 tar -xpv -C ${FSMNT} -f ${DDIR}/${di}.txz ${TAROPTS} >&1 2>&1
59 exit_err "ERROR: Failed extracting the dist file: $di"
63 # Check if this was a FTP download and clean it up now
64 if [ "${INSTALLMEDIUM}" = "ftp" ]; then
65 echo_log "Cleaning up downloaded archives"
69 echo_log "pc-sysinstall: Extraction Finished"
72 # Performs the extraction of data to disk from a uzip or tar archive
73 start_extract_uzip_tar()
75 if [ -z "$INSFILE" ]; then
76 exit_err "ERROR: Called extraction with no install file set!"
79 # Check if we have a .count file, and echo it out for a front-end to use in progress bars
80 if [ -e "${INSFILE}.count" ]; then
81 echo "INSTALLCOUNT: `cat ${INSFILE}.count`"
84 # Check if we are doing an upgrade, and if so use our exclude list
85 if [ "${INSTALLMODE}" = "upgrade" ]; then
86 TAROPTS="-X ${PROGDIR}/conf/exclude-from-upgrade"
91 echo_log "pc-sysinstall: Starting Extraction"
93 case ${PACKAGETYPE} in
95 if ! kldstat -v | grep -q "geom_uzip" ; then
96 exit_err "Kernel module geom_uzip not loaded"
99 # Start by mounting the uzip image
100 MDDEVICE=`mdconfig -a -t vnode -o readonly -f ${INSFILE}`
101 mkdir -p ${FSMNT}.uzip
102 mount -r /dev/${MDDEVICE}.uzip ${FSMNT}.uzip
105 exit_err "ERROR: Failed mounting the ${INSFILE}"
109 # Copy over all the files now!
110 tar cvf - . 2>/dev/null | tar -xpv -C ${FSMNT} ${TAROPTS} -f - 2>&1 | tee -a ${FSMNT}/.tar-extract.log
114 echo "TAR failure occurred:" >>${LOGOUT}
115 cat ${FSMNT}/.tar-extract.log | grep "tar:" >>${LOGOUT}
117 mdconfig -d -u ${MDDEVICE}
118 exit_err "ERROR: Failed extracting the tar image"
121 # All finished, now lets umount and cleanup
124 mdconfig -d -u ${MDDEVICE}
127 tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1
128 if [ $? -ne 0 ]; then
129 exit_err "ERROR: Failed extracting the tar image"
134 # Check if this was a FTP download and clean it up now
135 if [ "${INSTALLMEDIUM}" = "ftp" ]
137 echo_log "Cleaning up downloaded archive"
139 rm ${INSFILE}.count >/dev/null 2>/dev/null
140 rm ${INSFILE}.md5 >/dev/null 2>/dev/null
143 echo_log "pc-sysinstall: Extraction Finished"
147 # Performs the extraction of data to disk from a directory with split files
148 start_extract_split()
150 if [ -z "${INSDIR}" ]
152 exit_err "ERROR: Called extraction with no install directory set!"
155 echo_log "pc-sysinstall: Starting Extraction"
162 DIRS=`ls -d ${INSDIR}/*|grep -Ev '(uzip|kernels|src)'`
166 if [ -f "install.sh" ]
168 echo_log "Extracting" `basename ${dir}`
169 echo "y" | sh install.sh >/dev/null
172 exit_err "ERROR: Failed extracting ${dir}"
175 exit_err "ERROR: ${dir}/install.sh does not exist"
180 KERNELS=`ls -d ${INSDIR}/*|grep kernels`
182 if [ -f "install.sh" ]
184 echo_log "Extracting" `basename ${KERNELS}`
185 echo "y" | sh install.sh generic >/dev/null
188 exit_err "ERROR: Failed extracting ${KERNELS}"
190 rm -rf "${FSMNT}/boot/kernel"
191 mv "${FSMNT}/boot/GENERIC" "${FSMNT}/boot/kernel"
193 exit_err "ERROR: ${KERNELS}/install.sh does not exist"
197 SOURCE=`ls -d ${INSDIR}/*|grep src`
199 if [ -f "install.sh" ]
201 echo_log "Extracting" `basename ${SOURCE}`
202 echo "y" | sh install.sh all >/dev/null
205 exit_err "ERROR: Failed extracting ${SOURCE}"
208 exit_err "ERROR: ${SOURCE}/install.sh does not exist"
212 echo_log "pc-sysinstall: Extraction Finished"
215 # Function which will attempt to fetch the dist file(s) before we start
218 get_value_from_cfg ftpPath
221 exit_err "ERROR: Install medium was set to ftp, but no ftpPath was provided!"
226 # Check if we have a /usr partition to save the download
227 if [ -d "${FSMNT}/usr" ]
229 DLDIR="${FSMNT}/usr/.fetch.$$"
231 DLDIR="${FSMNT}/.fetch.$$"
235 # Do the fetch of the dist archive(s) now
238 fetch_file "${FTPPATH}/${di}.txz" "${DLDIR}/${di}.txz" "1"
241 # Check to see if there is a MANIFEST file for this install
242 fetch_file "${FTPPATH}/MANIFEST" "${DLDIR}/MANIFEST" "0"
247 # Function which will attempt to fetch the install file before we start
251 get_value_from_cfg ftpPath
254 exit_err "ERROR: Install medium was set to ftp, but no ftpPath was provided!"
259 # Check if we have a /usr partition to save the download
260 if [ -d "${FSMNT}/usr" ]
262 OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}"
264 OUTFILE="${FSMNT}/.fetch-${INSFILE}"
267 # Do the fetch of the archive now
268 fetch_file "${FTPPATH}/${INSFILE}" "${OUTFILE}" "1"
270 # Check to see if there is a .count file for this install
271 fetch_file "${FTPPATH}/${INSFILE}.count" "${OUTFILE}.count" "0"
273 # Check to see if there is a .md5 file for this install
274 fetch_file "${FTPPATH}/${INSFILE}.md5" "${OUTFILE}.md5" "0"
276 # Done fetching, now reset the INSFILE to our downloaded archived
277 export INSFILE="${OUTFILE}"
281 # Function which will download freebsd install files
287 exit_err "ERROR: Install medium was set to ftp, but no ftpHost was provided!"
294 exit_err "ERROR: Install medium was set to ftp, but no ftpDir was provided!"
298 # Check if we have a /usr partition to save the download
299 if [ -d "${FSMNT}/usr" ]
301 OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}"
303 OUTFILE="${FSMNT}/.fetch-${INSFILE}"
306 DIRS="base catpages dict doc games info manpages proflibs kernels src"
307 if [ "${FBSD_ARCH}" = "amd64" ]
314 mkdir -p "${OUTFILE}/${d}"
318 NETRC="${OUTFILE}/.netrc"
319 cat <<EOF >"${NETRC}"
330 cat <<EOF >>"${NETRC}"
337 cat <<EOF >>"${NETRC}"
343 # Fetch the files via ftp
344 echo "$ INSTALL" | ftp -N "${NETRC}" "${FTPHOST}"
346 # Done fetching, now reset the INSFILE to our downloaded archived
347 export INSFILE="${OUTFILE}"
350 # Function which does the rsync download from the server specified in cfg
353 # Load our rsync config values
354 get_value_from_cfg rsyncPath
355 if [ -z "${VAL}" ]; then
356 exit_err "ERROR: rsyncPath is unset! Please check your config and try again."
358 export RSYNCPATH="${VAL}"
360 get_value_from_cfg rsyncHost
361 if [ -z "${VAL}" ]; then
362 exit_err "ERROR: rsyncHost is unset! Please check your config and try again."
364 export RSYNCHOST="${VAL}"
366 get_value_from_cfg rsyncUser
367 if [ -z "${VAL}" ]; then
368 exit_err "ERROR: rsyncUser is unset! Please check your config and try again."
370 export RSYNCUSER="${VAL}"
372 get_value_from_cfg rsyncPort
373 if [ -z "${VAL}" ]; then
374 exit_err "ERROR: rsyncPort is unset! Please check your config and try again."
376 export RSYNCPORT="${VAL}"
382 if [ ${COUNT} -gt ${RSYNCTRIES} ]
384 exit_err "ERROR: Failed rsync command!"
389 --rsync-path="rsync --fake-super" \
390 -e "ssh -p ${RSYNCPORT}" \
391 ${RSYNCUSER}@${RSYNCHOST}:${RSYNCPATH}/./ ${FSMNT}
394 echo "Rsync failed! Tries: ${COUNT}"
404 start_image_install()
406 if [ -z "${IMAGE_FILE}" ]
408 exit_err "ERROR: installMedium set to image but no image file specified!"
411 # We are ready to start mounting, lets read the config and do it
414 echo $line | grep -q "^disk0=" 2>/dev/null
417 # Found a disk= entry, lets get the disk we are working on
418 get_value_from_string "${line}"
419 strip_white_space "$VAL"
423 echo $line | grep -q "^commitDiskPart" 2>/dev/null
426 # Found our flag to commit this disk setup / lets do sanity check and do it
431 write_image "${IMAGE_FILE}" "${DISK}"
433 # Increment our disk counter to look for next disk and unset
438 exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!"
445 # Entrance function, which starts the installation process
448 # Figure out what file we are using to install from via the config
449 get_value_from_cfg installFile
453 export INSFILE="${VAL}"
455 # If no installFile specified, try our defaults
456 if [ "$INSTALLTYPE" = "FreeBSD" ]
459 uzip) INSFILE="${FBSD_UZIP_FILE}" ;;
460 tar) INSFILE="${FBSD_TAR_FILE}" ;;
462 get_value_from_cfg_with_spaces distFiles
463 if [ -z "$VAL" ] ; then
464 exit_err "No dist files specified!"
469 INSDIR="${FBSD_BRANCH_DIR}"
471 # This is to trick opt_mount into not failing
477 uzip) INSFILE="${UZIP_FILE}" ;;
478 tar) INSFILE="${TAR_FILE}" ;;
480 get_value_from_cfg_with_spaces distFiles
481 if [ -z "$VAL" ] ; then
482 exit_err "No dist files specified!"
491 # Lets start by figuring out what medium we are using
492 case ${INSTALLMEDIUM} in
494 # Lets start by mounting the disk
496 if [ -n "${INSDIR}" ]
498 INSDIR="${CDMNT}/${INSDIR}" ; export INSDIR
502 if [ "$PACKAGETYPE" = "dist" ] ; then
503 start_extract_dist "${CDMNT}/usr/freebsd-dist"
505 INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE
506 start_extract_uzip_tar
516 INSDIR="${INSFILE}" ; export INSDIR
521 start_extract_dist "$DLDIR"
525 start_extract_uzip_tar
532 rsync) start_rsync_copy ;;
533 image) start_image_install ;;
535 get_value_from_cfg localPath
538 exit_err "Install medium was set to local, but no localPath was provided!"
541 if [ "$PACKAGETYPE" = "dist" ] ; then
542 INSFILE="${INSFILE}" ; export INSFILE
543 start_extract_dist "$LOCALPATH"
545 INSFILE="${LOCALPATH}/${INSFILE}" ; export INSFILE
546 start_extract_uzip_tar
549 *) exit_err "ERROR: Unknown install medium" ;;