source: src-sh/pc-sysinstall/backend/functions-extractimage.sh @ 89c5083

9.1-release9.2-releasereleng/10.0releng/10.0.1
Last change on this file since 89c5083 was 89c5083, checked in by Kris Moore <kris@…>, 12 months ago

Add patch to fix an extract issue

From: Bruce Simpson <bms@…>

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