functions-extractimage.sh revision 214189
1209513Simp#!/bin/sh
2209513Simp#-
3209552Simp# Copyright (c) 2010 iXsystems, Inc.  All rights reserved.
4209513Simp#
5209513Simp# Redistribution and use in source and binary forms, with or without
6209513Simp# modification, are permitted provided that the following conditions
7209513Simp# are met:
8209513Simp# 1. Redistributions of source code must retain the above copyright
9209513Simp#    notice, this list of conditions and the following disclaimer.
10209513Simp# 2. Redistributions in binary form must reproduce the above copyright
11209513Simp#    notice, this list of conditions and the following disclaimer in the
12209513Simp#    documentation and/or other materials provided with the distribution.
13209513Simp#
14209513Simp# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15209513Simp# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16209513Simp# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17209513Simp# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18209513Simp# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19209513Simp# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20209513Simp# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21209513Simp# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22209513Simp# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23209513Simp# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24209513Simp# SUCH DAMAGE.
25209513Simp#
26209513Simp# $FreeBSD: head/usr.sbin/pc-sysinstall/backend/functions-extractimage.sh 214189 2010-10-21 23:08:42Z imp $
27209513Simp
28209513Simp# Functions which perform the extraction / installation of system to disk
29209513Simp
30209513Simp. ${BACKEND}/functions-mountoptical.sh
31209513Simp
32209513Simp# Performs the extraction of data to disk from a uzip or tar archive
33209513Simpstart_extract_uzip_tar()
34209513Simp{
35209513Simp  if [ -z "$INSFILE" ]
36209513Simp  then
37209513Simp    exit_err "ERROR: Called extraction with no install file set!"
38209513Simp  fi
39209513Simp
40209513Simp  # Check if we have a .count file, and echo it out for a front-end to use in progress bars
41209513Simp  if [ -e "${INSFILE}.count" ]
42209513Simp  then
43209513Simp    echo "INSTALLCOUNT: `cat ${INSFILE}.count`"
44209513Simp  fi
45209513Simp
46209513Simp  # Check if we are doing an upgrade, and if so use our exclude list
47209513Simp  if [ "${INSTALLMODE}" = "upgrade" ]
48209513Simp  then
49209513Simp   TAROPTS="-X ${PROGDIR}/conf/exclude-from-upgrade"
50209513Simp  else
51209513Simp   TAROPTS=""
52209513Simp  fi
53209513Simp
54209513Simp  echo_log "pc-sysinstall: Starting Extraction"
55209513Simp
56209513Simp  case ${PACKAGETYPE} in
57211730Simp    uzip)
58211730Simp	  # Start by mounting the uzip image
59211730Simp      MDDEVICE=`mdconfig -a -t vnode -o readonly -f ${INSFILE}`
60211730Simp      mkdir -p ${FSMNT}.uzip
61211730Simp      mount -r /dev/${MDDEVICE}.uzip ${FSMNT}.uzip
62211730Simp      if [ "$?" != "0" ]
63211730Simp      then
64211730Simp        exit_err "ERROR: Failed mounting the ${INSFILE}"
65211730Simp      fi
66211730Simp      cd ${FSMNT}.uzip
67209513Simp
68211730Simp      # Copy over all the files now!
69211730Simp      tar cvf - . 2>/dev/null | tar -xpv -C ${FSMNT} ${TAROPTS} -f - 2>&1 | tee -a ${FSMNT}/.tar-extract.log
70211730Simp      if [ "$?" != "0" ]
71211730Simp      then
72211730Simp        cd /
73214189Simp        echo "TAR failure occurred:" >>${LOGOUT}
74211730Simp        cat ${FSMNT}/.tar-extract.log | grep "tar:" >>${LOGOUT}
75211730Simp        umount ${FSMNT}.uzip
76211730Simp        mdconfig -d -u ${MDDEVICE}
77211730Simp        exit_err "ERROR: Failed extracting the tar image"
78211730Simp      fi
79209513Simp
80211730Simp      # All finished, now lets umount and cleanup
81211730Simp      cd /
82211730Simp      umount ${FSMNT}.uzip
83211730Simp      mdconfig -d -u ${MDDEVICE}
84211730Simp       ;;
85211730Simp    tar)
86211730Simp	  tar -xpv -C ${FSMNT} -f ${INSFILE} ${TAROPTS} >&1 2>&1
87211730Simp      if [ "$?" != "0" ]
88211730Simp      then
89211730Simp        exit_err "ERROR: Failed extracting the tar image"
90211730Simp      fi
91211730Simp      ;;
92209513Simp  esac
93209513Simp
94209513Simp  # Check if this was a FTP download and clean it up now
95209513Simp  if [ "${INSTALLMEDIUM}" = "ftp" ]
96209513Simp  then
97209513Simp    echo_log "Cleaning up downloaded archive"
98209513Simp    rm ${INSFILE} 
99209513Simp    rm ${INSFILE}.count >/dev/null 2>/dev/null 
100209513Simp    rm ${INSFILE}.md5 >/dev/null 2>/dev/null
101209513Simp  fi
102209513Simp
103209513Simp  echo_log "pc-sysinstall: Extraction Finished"
104209513Simp
105209513Simp};
106209513Simp
107209513Simp# Performs the extraction of data to disk from a directory with split files
108209513Simpstart_extract_split()
109209513Simp{
110209513Simp  if [ -z "${INSDIR}" ]
111209513Simp  then
112209513Simp    exit_err "ERROR: Called extraction with no install directory set!"
113209513Simp  fi
114209513Simp
115209513Simp  echo_log "pc-sysinstall: Starting Extraction"
116209513Simp
117209513Simp  # Used by install.sh
118209513Simp  DESTDIR="${FSMNT}"
119209513Simp  export DESTDIR
120209513Simp
121209513Simp  HERE=`pwd`
122209513Simp  DIRS=`ls -d ${INSDIR}/*|grep -Ev '(uzip|kernels|src)'`
123209513Simp  for dir in ${DIRS}
124209513Simp  do
125211730Simp    cd "${dir}"
126211730Simp    if [ -f "install.sh" ]
127211730Simp    then
128211730Simp      echo_log "Extracting" `basename ${dir}`
129209513Simp      echo "y" | sh install.sh >/dev/null
130209513Simp      if [ "$?" != "0" ]
131209513Simp      then
132209513Simp        exit_err "ERROR: Failed extracting ${dir}"
133209513Simp      fi
134209513Simp    else
135209513Simp      exit_err "ERROR: ${dir}/install.sh does not exist"
136209513Simp    fi
137209513Simp  done
138209513Simp  cd "${HERE}"
139209513Simp  
140209513Simp  KERNELS=`ls -d ${INSDIR}/*|grep kernels`
141209513Simp  cd "${KERNELS}"
142209513Simp  if [ -f "install.sh" ]
143209513Simp  then
144211730Simp    echo_log "Extracting" `basename ${KERNELS}`
145209513Simp    echo "y" | sh install.sh generic >/dev/null
146209513Simp    if [ "$?" != "0" ]
147209513Simp    then
148209513Simp      exit_err "ERROR: Failed extracting ${KERNELS}"
149209513Simp    fi
150213650Simp    rm -rf "${FSMNT}/boot/kernel"
151211730Simp    mv "${FSMNT}/boot/GENERIC" "${FSMNT}/boot/kernel"
152209513Simp  else
153209513Simp    exit_err "ERROR: ${KERNELS}/install.sh does not exist"
154209513Simp  fi
155209513Simp  cd "${HERE}"
156209513Simp
157209513Simp  SOURCE=`ls -d ${INSDIR}/*|grep src`
158209513Simp  cd "${SOURCE}"
159209513Simp  if [ -f "install.sh" ]
160209513Simp  then
161211730Simp    echo_log "Extracting" `basename ${SOURCE}`
162209513Simp    echo "y" | sh install.sh all >/dev/null
163209513Simp    if [ "$?" != "0" ]
164209513Simp    then
165209513Simp      exit_err "ERROR: Failed extracting ${SOURCE}"
166209513Simp    fi
167209513Simp  else
168209513Simp    exit_err "ERROR: ${SOURCE}/install.sh does not exist"
169209513Simp  fi
170209513Simp  cd "${HERE}"
171209513Simp
172209513Simp  echo_log "pc-sysinstall: Extraction Finished"
173209513Simp};
174209513Simp
175209513Simp# Function which will attempt to fetch the install file before we start
176209513Simp# the install
177209513Simpfetch_install_file()
178209513Simp{
179209513Simp  get_value_from_cfg ftpPath
180209513Simp  if [ -z "$VAL" ]
181209513Simp  then
182209513Simp    exit_err "ERROR: Install medium was set to ftp, but no ftpPath was provided!" 
183209513Simp  fi
184209513Simp
185209513Simp  FTPPATH="${VAL}"
186209513Simp  
187209513Simp  # Check if we have a /usr partition to save the download
188209513Simp  if [ -d "${FSMNT}/usr" ]
189209513Simp  then
190209513Simp    OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}"
191209513Simp  else
192209513Simp    OUTFILE="${FSMNT}/.fetch-${INSFILE}"
193209513Simp  fi
194209513Simp
195209513Simp  # Do the fetch of the archive now
196209513Simp  fetch_file "${FTPPATH}/${INSFILE}" "${OUTFILE}" "1"
197209513Simp
198209513Simp  # Check to see if there is a .count file for this install
199209513Simp  fetch_file "${FTPPATH}/${INSFILE}.count" "${OUTFILE}.count" "0"
200209513Simp
201209513Simp  # Check to see if there is a .md5 file for this install
202209513Simp  fetch_file "${FTPPATH}/${INSFILE}.md5" "${OUTFILE}.md5" "0"
203209513Simp
204209513Simp  # Done fetching, now reset the INSFILE to our downloaded archived
205209513Simp  INSFILE="${OUTFILE}" ; export INSFILE
206209513Simp
207209513Simp};
208209513Simp
209211486Simp# Function which will download freebsd install files
210211486Simpfetch_split_files()
211211486Simp{
212211730Simp  get_ftpHost
213211486Simp  if [ -z "$VAL" ]
214211486Simp  then
215211486Simp    exit_err "ERROR: Install medium was set to ftp, but no ftpHost was provided!" 
216211486Simp  fi
217211486Simp  FTPHOST="${VAL}"
218211486Simp
219211730Simp  get_ftpDir
220211486Simp  if [ -z "$VAL" ]
221211486Simp  then
222211486Simp    exit_err "ERROR: Install medium was set to ftp, but no ftpDir was provided!" 
223211486Simp  fi
224211486Simp  FTPDIR="${VAL}"
225211486Simp
226211486Simp  # Check if we have a /usr partition to save the download
227211486Simp  if [ -d "${FSMNT}/usr" ]
228211486Simp  then
229211486Simp    OUTFILE="${FSMNT}/usr/.fetch-${INSFILE}"
230211486Simp  else
231211486Simp    OUTFILE="${FSMNT}/.fetch-${INSFILE}"
232211486Simp  fi
233211486Simp
234211730Simp  DIRS="base catpages dict doc games info manpages proflibs kernels src"
235211730Simp  if [ "${FBSD_ARCH}" = "amd64" ]
236211730Simp  then
237211730Simp    DIRS="${DIRS} lib32"
238211730Simp  fi
239211730Simp
240211730Simp  for d in ${DIRS}
241211730Simp  do
242211730Simp    mkdir -p "${OUTFILE}/${d}"
243211730Simp  done
244211730Simp
245211730Simp
246211486Simp  NETRC="${OUTFILE}/.netrc"
247211486Simp  cat<<EOF>"${NETRC}"
248211486Simpmachine ${FTPHOST}
249211486Simplogin anonymous
250211486Simppassword anonymous
251211486Simpmacdef INSTALL
252211486Simpbin
253211486Simpprompt
254211486SimpEOF
255211486Simp
256211486Simp  for d in ${DIRS}
257211486Simp  do
258211730Simp    cat<<EOF>>"${NETRC}"
259211486Simpcd ${FTPDIR}/${d}
260211486Simplcd ${OUTFILE}/${d}
261211486Simpmreget *
262211486SimpEOF
263211486Simp  done
264211486Simp
265211730Simp  cat<<EOF>>"${NETRC}"
266211486Simpbye
267211486Simp
268211486Simp
269211486SimpEOF
270211486Simp
271211487Simp  # Fetch the files via ftp
272211487Simp  echo "$ INSTALL" | ftp -N "${NETRC}" "${FTPHOST}"
273211486Simp
274211486Simp  # Done fetching, now reset the INSFILE to our downloaded archived
275211486Simp  INSFILE="${OUTFILE}" ; export INSFILE
276211486Simp}
277211486Simp
278214189Simp# Function which does the rsync download from the server specified in cfg
279209513Simpstart_rsync_copy()
280209513Simp{
281209513Simp  # Load our rsync config values
282209513Simp  get_value_from_cfg rsyncPath
283209513Simp  if [ -z "${VAL}" ]; then
284209513Simp    exit_err "ERROR: rsyncPath is unset! Please check your config and try again."
285209513Simp  fi
286209513Simp  RSYNCPATH="${VAL}" ; export RSYNCPATH
287209513Simp
288209513Simp  get_value_from_cfg rsyncHost
289209513Simp  if [  -z "${VAL}" ]; then
290209513Simp    exit_err "ERROR: rsyncHost is unset! Please check your config and try again."
291209513Simp  fi
292209513Simp  RSYNCHOST="${VAL}" ; export RSYNCHOST
293209513Simp
294209513Simp  get_value_from_cfg rsyncUser
295209513Simp  if [ -z "${VAL}" ]; then
296209513Simp    exit_err "ERROR: rsyncUser is unset! Please check your config and try again."
297209513Simp  fi
298209513Simp  RSYNCUSER="${VAL}" ; export RSYNCUSER
299209513Simp
300209513Simp  get_value_from_cfg rsyncPort
301209513Simp  if [ -z "${VAL}" ]; then
302209513Simp    exit_err "ERROR: rsyncPort is unset! Please check your config and try again."
303209513Simp  fi
304209513Simp  RSYNCPORT="${VAL}" ; export RSYNCPORT
305209513Simp
306209513Simp  COUNT="1"
307209513Simp  while
308209513Simp  z=1
309209513Simp  do
310209513Simp    if [ ${COUNT} -gt ${RSYNCTRIES} ]
311209513Simp    then
312209513Simp     exit_err "ERROR: Failed rsync command!"
313209513Simp     break
314209513Simp    fi
315209513Simp
316209513Simp    rsync -avvzHsR \
317209513Simp    --rsync-path="rsync --fake-super" \
318209513Simp    -e "ssh -p ${RSYNCPORT}" \
319209513Simp    ${RSYNCUSER}@${RSYNCHOST}:${RSYNCPATH}/./ ${FSMNT}
320209513Simp    if [ "$?" != "0" ]
321209513Simp    then
322209513Simp      echo "Rsync failed! Tries: ${COUNT}"
323209513Simp    else
324209513Simp      break
325209513Simp    fi
326209513Simp
327209513Simp    COUNT="`expr ${COUNT} + 1`"
328209513Simp  done 
329209513Simp
330209513Simp};
331209513Simp
332213650Simpstart_image_install()
333213650Simp{
334213650Simp  if [ -z "${IMAGE_FILE}" ]
335213650Simp  then
336213650Simp    exit_err "ERROR: installMedium set to image but no image file specified!"
337213650Simp  fi
338209513Simp
339213650Simp  # We are ready to start mounting, lets read the config and do it
340213650Simp  while read line
341213650Simp  do
342213650Simp    echo $line | grep "^disk0=" >/dev/null 2>/dev/null
343213650Simp    if [ "$?" = "0" ]
344213650Simp    then
345213650Simp      # Found a disk= entry, lets get the disk we are working on
346213650Simp      get_value_from_string "${line}"
347213650Simp      strip_white_space "$VAL"
348213650Simp      DISK="$VAL"
349213650Simp    fi
350213650Simp
351213650Simp    echo $line | grep "^commitDiskPart" >/dev/null 2>/dev/null
352213650Simp    if [ "$?" = "0" ]
353213650Simp    then
354213650Simp      # Found our flag to commit this disk setup / lets do sanity check and do it
355213650Simp      if [ ! -z "${DISK}" ]
356213650Simp      then
357213650Simp
358213650Simp        # Write the image
359213650Simp        write_image "${IMAGE_FILE}" "${DISK}"
360213650Simp
361213650Simp        # Increment our disk counter to look for next disk and unset
362213650Simp        unset DISK
363213650Simp        break
364213650Simp
365213650Simp      else
366213650Simp        exit_err "ERROR: commitDiskPart was called without procceding disk<num>= and partition= entries!!!"
367213650Simp      fi
368213650Simp    fi
369213650Simp
370213650Simp  done <${CFGF}
371213650Simp};
372213650Simp
373209513Simp# Entrance function, which starts the installation process
374209513Simpinit_extraction()
375209513Simp{
376209513Simp  # Figure out what file we are using to install from via the config
377209513Simp  get_value_from_cfg installFile
378209513Simp
379209513Simp  if [ ! -z "${VAL}" ]
380209513Simp  then
381209513Simp    INSFILE="${VAL}" ; export INSFILE
382209513Simp  else
383209513Simp    # If no installFile specified, try our defaults
384209513Simp    if [ "$INSTALLTYPE" = "FreeBSD" ]
385209513Simp    then
386209513Simp      case $PACKAGETYPE in
387211730Simp        uzip) INSFILE="${FBSD_UZIP_FILE}" ;;
388211730Simp        tar) INSFILE="${FBSD_TAR_FILE}" ;;
389211730Simp        split)
390211730Simp          INSDIR="${FBSD_BRANCH_DIR}"
391209513Simp
392211730Simp          # This is to trick opt_mount into not failing
393211730Simp          INSFILE="${INSDIR}"
394211730Simp          ;;
395209513Simp      esac
396209513Simp    else
397209513Simp      case $PACKAGETYPE in
398211730Simp        uzip) INSFILE="${UZIP_FILE}" ;;
399211730Simp        tar) INSFILE="${TAR_FILE}" ;;
400209513Simp      esac
401209513Simp    fi
402209513Simp    export INSFILE
403209513Simp  fi
404209513Simp
405209513Simp  # Lets start by figuring out what medium we are using
406209513Simp  case ${INSTALLMEDIUM} in
407211730Simp    dvd|usb)
408211730Simp      # Lets start by mounting the disk 
409211730Simp      opt_mount 
410211730Simp      if [ ! -z "${INSDIR}" ]
411211730Simp      then
412211730Simp        INSDIR="${CDMNT}/${INSDIR}" ; export INSDIR
413211730Simp	    start_extract_split
414209513Simp
415211730Simp      else
416211730Simp        INSFILE="${CDMNT}/${INSFILE}" ; export INSFILE
417211730Simp        start_extract_uzip_tar
418211730Simp      fi
419211730Simp      ;;
420211486Simp
421212337Simp    ftp)
422211730Simp      if [ "$PACKAGETYPE" = "split" ]
423211730Simp      then
424211730Simp        fetch_split_files
425211730Simp
426211730Simp        INSDIR="${INSFILE}" ; export INSDIR
427211730Simp        start_extract_split
428211730Simp      else
429211730Simp        fetch_install_file
430211730Simp        start_extract_uzip_tar 
431211730Simp      fi
432211730Simp      ;;
433211730Simp
434212337Simp    sftp) ;;
435212337Simp
436212337Simp    rsync) start_rsync_copy ;;
437213650Simp    image) start_image_install ;;
438211730Simp    *) exit_err "ERROR: Unknown install medium" ;;
439209513Simp  esac
440209513Simp
441209513Simp};
442