functions-extractimage.sh revision 211487
1178825Sdfr#!/bin/sh
2178825Sdfr#-
3178825Sdfr# Copyright (c) 2010 iXsystems, Inc.  All rights reserved.
4178825Sdfr#
5178825Sdfr# Redistribution and use in source and binary forms, with or without
6233294Sstas# modification, are permitted provided that the following conditions
7178825Sdfr# are met:
8178825Sdfr# 1. Redistributions of source code must retain the above copyright
9178825Sdfr#    notice, this list of conditions and the following disclaimer.
10178825Sdfr# 2. Redistributions in binary form must reproduce the above copyright
11178825Sdfr#    notice, this list of conditions and the following disclaimer in the
12178825Sdfr#    documentation and/or other materials provided with the distribution.
13178825Sdfr#
14178825Sdfr# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15178825Sdfr# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16178825Sdfr# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17178825Sdfr# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18178825Sdfr# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19178825Sdfr# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20178825Sdfr# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21178825Sdfr# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22178825Sdfr# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23178825Sdfr# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24178825Sdfr# SUCH DAMAGE.
25178825Sdfr#
26178825Sdfr# $FreeBSD: head/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh 211487 2010-08-19 06:02:31Z imp $
27178825Sdfr
28178825Sdfr# Functions which perform the extraction / installation of system to disk
29178825Sdfr
30178825Sdfr. ${BACKEND}/functions-mountoptical.sh
31178825Sdfr
32178825Sdfr# Performs the extraction of data to disk from a uzip or tar archive
33178825Sdfrstart_extract_uzip_tar()
34178825Sdfr{
35178825Sdfr  if [ -z "$INSFILE" ]
36178825Sdfr  then
37178825Sdfr    exit_err "ERROR: Called extraction with no install file set!"
38178825Sdfr  fi
39178825Sdfr
40178825Sdfr  # Check if we have a .count file, and echo it out for a front-end to use in progress bars
41178825Sdfr  if [ -e "${INSFILE}.count" ]
42178825Sdfr  then
43178825Sdfr    echo "INSTALLCOUNT: `cat ${INSFILE}.count`"
44178825Sdfr  fi
45178825Sdfr
46178825Sdfr  # Check if we are doing an upgrade, and if so use our exclude list
47178825Sdfr  if [ "${INSTALLMODE}" = "upgrade" ]
48178825Sdfr  then
49178825Sdfr   TAROPTS="-X ${PROGDIR}/conf/exclude-from-upgrade"
50178825Sdfr  else
51178825Sdfr   TAROPTS=""
52178825Sdfr  fi
53178825Sdfr
54178825Sdfr  echo_log "pc-sysinstall: Starting Extraction"
55178825Sdfr
56178825Sdfr  case ${PACKAGETYPE} in
57178825Sdfr   uzip) # Start by mounting the uzip image
58178825Sdfr         MDDEVICE=`mdconfig -a -t vnode -o readonly -f ${INSFILE}`
59178825Sdfr         mkdir -p ${FSMNT}.uzip
60178825Sdfr         mount -r /dev/${MDDEVICE}.uzip ${FSMNT}.uzip
61178825Sdfr         if [ "$?" != "0" ]
62178825Sdfr         then
63178825Sdfr           exit_err "ERROR: Failed mounting the ${INSFILE}"
64178825Sdfr         fi
65233294Sstas         cd ${FSMNT}.uzip
66233294Sstas
67178825Sdfr         # Copy over all the files now!
68233294Sstas         tar cvf - . 2>/dev/null | tar -xpv -C ${FSMNT} ${TAROPTS} -f - 2>&1 | tee -a ${FSMNT}/.tar-extract.log
69233294Sstas         if [ "$?" != "0" ]
70178825Sdfr         then
71178825Sdfr           cd /
72178825Sdfr           echo "TAR failure occured:" >>${LOGOUT}
73178825Sdfr           cat ${FSMNT}/.tar-extract.log | grep "tar:" >>${LOGOUT}
74178825Sdfr           umount ${FSMNT}.uzip
75178825Sdfr           mdconfig -d -u ${MDDEVICE}
76178825Sdfr           exit_err "ERROR: Failed extracting the tar image"
77178825Sdfr         fi
78178825Sdfr
79178825Sdfr         # All finished, now lets umount and cleanup
80178825Sdfr         cd /
81178825Sdfr         umount ${FSMNT}.uzip
82178825Sdfr         mdconfig -d -u ${MDDEVICE}
83178825Sdfr         ;;
84178825Sdfr    tar) tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1
85178825Sdfr         if [ "$?" != "0" ]
86178825Sdfr         then
87178825Sdfr           exit_err "ERROR: Failed extracting the tar image"
88178825Sdfr         fi
89178825Sdfr         ;;
90178825Sdfr  esac
91178825Sdfr
92178825Sdfr  # Check if this was a FTP download and clean it up now
93178825Sdfr  if [ "${INSTALLMEDIUM}" = "ftp" ]
94178825Sdfr  then
95178825Sdfr    echo_log "Cleaning up downloaded archive"
96178825Sdfr    rm ${INSFILE} 
97178825Sdfr    rm ${INSFILE}.count >/dev/null 2>/dev/null 
98178825Sdfr    rm ${INSFILE}.md5 >/dev/null 2>/dev/null
99178825Sdfr  fi
100178825Sdfr
101178825Sdfr  echo_log "pc-sysinstall: Extraction Finished"
102178825Sdfr
103178825Sdfr};
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_log "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_log "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_log "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 will download freebsd install files
207fetch_split_files()
208{
209  get_value_from_cfg ftpHost
210  if [ -z "$VAL" ]
211  then
212    exit_err "ERROR: Install medium was set to ftp, but no ftpHost was provided!" 
213  fi
214  FTPHOST="${VAL}"
215
216  get_value_from_cfg ftpDir
217  if [ -z "$VAL" ]
218  then
219    exit_err "ERROR: Install medium was set to ftp, but no ftpDir was provided!" 
220  fi
221  FTPDIR="${VAL}"
222
223  # Check if we have a /usr partition to save the download
224  if [ -d "${FSMNT}/usr" ]
225  then
226    OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}"
227  else
228    OUTFILE="${FSMNT}/.fetch-${INSFILE}"
229  fi
230
231  NETRC="${OUTFILE}/.netrc"
232  cat<<EOF>"${NETRC}"
233machine ${FTPHOST}
234login anonymous
235password anonymous
236macdef INSTALL
237bin
238prompt
239EOF
240
241  DIRS="base catpages dict doc games info manpages proflibs kernels src"
242  if [ "${FBSD_ARCH}" = "amd64" ]
243  then
244	DIRS="${DIRS} lib32"
245  fi
246
247  for d in ${DIRS}
248  do
249	cat<<EOF>>"${NETRC}"
250cd ${FTPDIR}/${d}
251lcd ${OUTFILE}/${d}
252mreget *
253EOF
254  done
255
256	cat<<EOF>>"${NETRC}"
257bye
258
259
260EOF
261
262  # Fetch the files via ftp
263  echo "$ INSTALL" | ftp -N "${NETRC}" "${FTPHOST}"
264
265  # Done fetching, now reset the INSFILE to our downloaded archived
266  INSFILE="${OUTFILE}" ; export INSFILE
267}
268
269# Function which does the rsync download from the server specifed in cfg
270start_rsync_copy()
271{
272  # Load our rsync config values
273  get_value_from_cfg rsyncPath
274  if [ -z "${VAL}" ]; then
275    exit_err "ERROR: rsyncPath is unset! Please check your config and try again."
276  fi
277  RSYNCPATH="${VAL}" ; export RSYNCPATH
278
279  get_value_from_cfg rsyncHost
280  if [  -z "${VAL}" ]; then
281    exit_err "ERROR: rsyncHost is unset! Please check your config and try again."
282  fi
283  RSYNCHOST="${VAL}" ; export RSYNCHOST
284
285  get_value_from_cfg rsyncUser
286  if [ -z "${VAL}" ]; then
287    exit_err "ERROR: rsyncUser is unset! Please check your config and try again."
288  fi
289  RSYNCUSER="${VAL}" ; export RSYNCUSER
290
291  get_value_from_cfg rsyncPort
292  if [ -z "${VAL}" ]; then
293    exit_err "ERROR: rsyncPort is unset! Please check your config and try again."
294  fi
295  RSYNCPORT="${VAL}" ; export RSYNCPORT
296
297  COUNT="1"
298  while
299  z=1
300  do
301    if [ ${COUNT} -gt ${RSYNCTRIES} ]
302    then
303     exit_err "ERROR: Failed rsync command!"
304     break
305    fi
306
307    rsync -avvzHsR \
308    --rsync-path="rsync --fake-super" \
309    -e "ssh -p ${RSYNCPORT}" \
310    ${RSYNCUSER}@${RSYNCHOST}:${RSYNCPATH}/./ ${FSMNT}
311    if [ "$?" != "0" ]
312    then
313      echo "Rsync failed! Tries: ${COUNT}"
314    else
315      break
316    fi
317
318    COUNT="`expr ${COUNT} + 1`"
319  done 
320
321};
322
323
324# Entrance function, which starts the installation process
325init_extraction()
326{
327  # Figure out what file we are using to install from via the config
328  get_value_from_cfg installFile
329
330  if [ ! -z "${VAL}" ]
331  then
332    INSFILE="${VAL}" ; export INSFILE
333  else
334    # If no installFile specified, try our defaults
335    if [ "$INSTALLTYPE" = "FreeBSD" ]
336    then
337      case $PACKAGETYPE in
338         uzip) INSFILE="${FBSD_UZIP_FILE}" ;;
339          tar) INSFILE="${FBSD_TAR_FILE}" ;;
340		  split)
341			INSDIR="${FBSD_BRANCH_DIR}"
342
343			# This is to trick opt_mount into not failing
344			INSFILE="${INSDIR}"
345			;;
346      esac
347    else
348      case $PACKAGETYPE in
349         uzip) INSFILE="${UZIP_FILE}" ;;
350          tar) INSFILE="${TAR_FILE}" ;;
351      esac
352    fi
353    export INSFILE
354  fi
355
356  # Lets start by figuring out what medium we are using
357  case ${INSTALLMEDIUM} in
358 dvd|usb) # Lets start by mounting the disk 
359          opt_mount 
360		  if [ ! -z "${INSDIR}" ]
361		  then
362          	INSDIR="${CDMNT}/${INSDIR}" ; export INSDIR
363			start_extract_split
364
365		  else
366          	INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE
367          	start_extract_uzip_tar
368		  fi
369          ;;
370     ftp)
371		  if [ "$PACKAGETYPE" = "split" ]
372		  then
373			fetch_split_files
374
375			INSDIR="${INSFILE}" ; export INSDIR
376			start_extract_split
377		  else
378          	fetch_install_file
379          	start_extract_uzip_tar 
380		  fi
381          ;;
382     rsync) start_rsync_copy
383            ;;
384       *) exit_err "ERROR: Unknown install medium" ;;
385  esac
386
387};
388