functions-extractimage.sh revision 209552
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 209552 2010-06-27 16:46:11Z 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) # Start by mounting the uzip image
58         MDDEVICE=`mdconfig -a -t vnode -o readonly -f ${INSFILE}`
59         mkdir -p ${FSMNT}.uzip
60         mount -r /dev/${MDDEVICE}.uzip ${FSMNT}.uzip
61         if [ "$?" != "0" ]
62         then
63           exit_err "ERROR: Failed mounting the ${INSFILE}"
64         fi
65         cd ${FSMNT}.uzip
66
67         # Copy over all the files now!
68         tar cvf - . 2>/dev/null | tar -xpv -C ${FSMNT} ${TAROPTS} -f - 2>&1 | tee -a ${FSMNT}/.tar-extract.log
69         if [ "$?" != "0" ]
70         then
71           cd /
72           echo "TAR failure occured:" >>${LOGOUT}
73           cat ${FSMNT}/.tar-extract.log | grep "tar:" >>${LOGOUT}
74           umount ${FSMNT}.uzip
75           mdconfig -d -u ${MDDEVICE}
76           exit_err "ERROR: Failed extracting the tar image"
77         fi
78
79         # All finished, now lets umount and cleanup
80         cd /
81         umount ${FSMNT}.uzip
82         mdconfig -d -u ${MDDEVICE}
83         ;;
84    tar) tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1
85         if [ "$?" != "0" ]
86         then
87           exit_err "ERROR: Failed extracting the tar image"
88         fi
89         ;;
90  esac
91
92  # Check if this was a FTP download and clean it up now
93  if [ "${INSTALLMEDIUM}" = "ftp" ]
94  then
95    echo_log "Cleaning up downloaded archive"
96    rm ${INSFILE} 
97    rm ${INSFILE}.count >/dev/null 2>/dev/null 
98    rm ${INSFILE}.md5 >/dev/null 2>/dev/null
99  fi
100
101  echo_log "pc-sysinstall: Extraction Finished"
102
103};
104
105# Performs the extraction of data to disk from a directory with split files
106start_extract_split()
107{
108  if [ -z "${INSDIR}" ]
109  then
110    exit_err "ERROR: Called extraction with no install directory set!"
111  fi
112
113  echo_log "pc-sysinstall: Starting Extraction"
114
115  # Used by install.sh
116  DESTDIR="${FSMNT}"
117  export DESTDIR
118
119  HERE=`pwd`
120  DIRS=`ls -d ${INSDIR}/*|grep -Ev '(uzip|kernels|src)'`
121  for dir in ${DIRS}
122  do
123	cd "${dir}"
124	if [ -f "install.sh" ]
125	then
126	  echo "Extracting" `basename ${dir}`
127      echo "y" | sh install.sh >/dev/null
128      if [ "$?" != "0" ]
129      then
130        exit_err "ERROR: Failed extracting ${dir}"
131      fi
132    else
133      exit_err "ERROR: ${dir}/install.sh does not exist"
134    fi
135  done
136  cd "${HERE}"
137  
138  KERNELS=`ls -d ${INSDIR}/*|grep kernels`
139  cd "${KERNELS}"
140  if [ -f "install.sh" ]
141  then
142	echo "Extracting" `basename ${KERNELS}`
143    echo "y" | sh install.sh generic >/dev/null
144    if [ "$?" != "0" ]
145    then
146      exit_err "ERROR: Failed extracting ${KERNELS}"
147    fi
148	echo 'kernel="GENERIC"' > "${FSMNT}/boot/loader.conf"
149  else
150    exit_err "ERROR: ${KERNELS}/install.sh does not exist"
151  fi
152  cd "${HERE}"
153
154  SOURCE=`ls -d ${INSDIR}/*|grep src`
155  cd "${SOURCE}"
156  if [ -f "install.sh" ]
157  then
158	echo "Extracting" `basename ${SOURCE}`
159    echo "y" | sh install.sh all >/dev/null
160    if [ "$?" != "0" ]
161    then
162      exit_err "ERROR: Failed extracting ${SOURCE}"
163    fi
164  else
165    exit_err "ERROR: ${SOURCE}/install.sh does not exist"
166  fi
167  cd "${HERE}"
168
169  echo_log "pc-sysinstall: Extraction Finished"
170};
171
172# Function which will attempt to fetch the install file before we start
173# the install
174fetch_install_file()
175{
176  get_value_from_cfg ftpPath
177  if [ -z "$VAL" ]
178  then
179    exit_err "ERROR: Install medium was set to ftp, but no ftpPath was provided!" 
180  fi
181
182  FTPPATH="${VAL}"
183  
184  # Check if we have a /usr partition to save the download
185  if [ -d "${FSMNT}/usr" ]
186  then
187    OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}"
188  else
189    OUTFILE="${FSMNT}/.fetch-${INSFILE}"
190  fi
191
192  # Do the fetch of the archive now
193  fetch_file "${FTPPATH}/${INSFILE}" "${OUTFILE}" "1"
194
195  # Check to see if there is a .count file for this install
196  fetch_file "${FTPPATH}/${INSFILE}.count" "${OUTFILE}.count" "0"
197
198  # Check to see if there is a .md5 file for this install
199  fetch_file "${FTPPATH}/${INSFILE}.md5" "${OUTFILE}.md5" "0"
200
201  # Done fetching, now reset the INSFILE to our downloaded archived
202  INSFILE="${OUTFILE}" ; export INSFILE
203
204};
205
206# Function which does the rsync download from the server specifed in cfg
207start_rsync_copy()
208{
209  # Load our rsync config values
210  get_value_from_cfg rsyncPath
211  if [ -z "${VAL}" ]; then
212    exit_err "ERROR: rsyncPath is unset! Please check your config and try again."
213  fi
214  RSYNCPATH="${VAL}" ; export RSYNCPATH
215
216  get_value_from_cfg rsyncHost
217  if [  -z "${VAL}" ]; then
218    exit_err "ERROR: rsyncHost is unset! Please check your config and try again."
219  fi
220  RSYNCHOST="${VAL}" ; export RSYNCHOST
221
222  get_value_from_cfg rsyncUser
223  if [ -z "${VAL}" ]; then
224    exit_err "ERROR: rsyncUser is unset! Please check your config and try again."
225  fi
226  RSYNCUSER="${VAL}" ; export RSYNCUSER
227
228  get_value_from_cfg rsyncPort
229  if [ -z "${VAL}" ]; then
230    exit_err "ERROR: rsyncPort is unset! Please check your config and try again."
231  fi
232  RSYNCPORT="${VAL}" ; export RSYNCPORT
233
234  COUNT="1"
235  while
236  z=1
237  do
238    if [ ${COUNT} -gt ${RSYNCTRIES} ]
239    then
240     exit_err "ERROR: Failed rsync command!"
241     break
242    fi
243
244    rsync -avvzHsR \
245    --rsync-path="rsync --fake-super" \
246    -e "ssh -p ${RSYNCPORT}" \
247    ${RSYNCUSER}@${RSYNCHOST}:${RSYNCPATH}/./ ${FSMNT}
248    if [ "$?" != "0" ]
249    then
250      echo "Rsync failed! Tries: ${COUNT}"
251    else
252      break
253    fi
254
255    COUNT="`expr ${COUNT} + 1`"
256  done 
257
258};
259
260
261# Entrance function, which starts the installation process
262init_extraction()
263{
264  # Figure out what file we are using to install from via the config
265  get_value_from_cfg installFile
266
267  if [ ! -z "${VAL}" ]
268  then
269    INSFILE="${VAL}" ; export INSFILE
270  else
271    # If no installFile specified, try our defaults
272    if [ "$INSTALLTYPE" = "FreeBSD" ]
273    then
274      case $PACKAGETYPE in
275         uzip) INSFILE="${FBSD_UZIP_FILE}" ;;
276          tar) INSFILE="${FBSD_TAR_FILE}" ;;
277		  split)
278			INSDIR="${FBSD_BRANCH_DIR}"
279
280			# This is to trick opt_mount into not failing
281			INSFILE="${INSDIR}"
282			;;
283      esac
284    else
285      case $PACKAGETYPE in
286         uzip) INSFILE="${UZIP_FILE}" ;;
287          tar) INSFILE="${TAR_FILE}" ;;
288      esac
289    fi
290    export INSFILE
291  fi
292
293  # Lets start by figuring out what medium we are using
294  case ${INSTALLMEDIUM} in
295 dvd|usb) # Lets start by mounting the disk 
296          opt_mount 
297		  if [ ! -z "${INSDIR}" ]
298		  then
299          	INSDIR="${CDMNT}/${INSDIR}" ; export INSDIR
300			start_extract_split
301
302		  else
303          	INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE
304          	start_extract_uzip_tar
305		  fi
306          ;;
307     ftp) fetch_install_file
308          start_extract_uzip_tar 
309          ;;
310     rsync) start_rsync_copy
311            ;;
312       *) exit_err "ERROR: Unknown install medium" ;;
313  esac
314
315};
316