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: releng/10.3/usr.sbin/pc-sysinstall/backend/functions-installpackages.sh 247734 2013-03-03 23:01:46Z jpaetzel $
27
28# Functions which check and load any optional packages specified in the config
29
30. ${BACKEND}/functions.sh
31. ${BACKEND}/functions-parse.sh
32
33# Recursively determine all dependencies for this package
34determine_package_dependencies()
35{
36  local PKGNAME="${1}"
37  local DEPFILE="${2}"
38
39  grep -q "${PKGNAME}" "${DEPFILE}"
40  if [ $? -ne 0 ]
41  then
42    echo "${PKGNAME}" >> "${DEPFILE}"
43    get_package_dependencies "${PKGNAME}" "1"
44
45    local DEPS="${VAL}"
46    for d in ${DEPS}
47    do
48      determine_package_dependencies "${d}" "${DEPFILE}"
49    done
50  fi
51};
52
53# Fetch packages dependencies from a file
54fetch_package_dependencies()
55{
56  local DEPFILE
57  local DEPS
58  local SAVEDIR
59
60  DEPFILE="${1}"
61  DEPS=`cat "${DEPFILE}"`
62  SAVEDIR="${2}"
63
64  for d in ${DEPS}
65  do
66    get_package_short_name "${d}"
67    SNAME="${VAL}"
68
69    get_package_category "${SNAME}"
70    CATEGORY="${VAL}"
71
72    fetch_package "${CATEGORY}" "${d}" "${SAVEDIR}"
73  done
74};
75
76# Check for any packages specified, and begin loading them
77install_packages()
78{
79  echo "Checking for packages to install..."
80  sleep 2
81
82  # First, lets check and see if we even have any packages to install
83  get_value_from_cfg installPackages
84
85  # Nothing to do?
86  if [ -z "${VAL}" ]; then return; fi
87
88  echo "Installing packages..."
89  sleep 3
90
91  local PKGPTH
92
93  HERE=`pwd`
94  rc_halt "mkdir -p ${FSMNT}${PKGTMPDIR}"
95
96  # Determine the directory we will install packages from
97  get_package_location
98  rc_halt "cd ${PKGDLDIR}"
99
100  # Set the location of the INDEXFILE
101  INDEXFILE="${TMPDIR}/INDEX"
102
103  if [ ! -f "${INDEXFILE}" ]; then
104    get_package_index
105  fi
106
107  if [ ! -f "${TMPDIR}/INDEX.parsed" -a "$INSTALLMEDIUM" = "ftp" ]; then
108    parse_package_index
109  fi
110
111  # What extension are we using for pkgs?
112  PKGEXT="txz"
113  get_value_from_cfg pkgExt
114  if [ -n "${VAL}" ]; then 
115     strip_white_space ${VAL}
116     PKGEXT="$VAL"
117  fi
118  export PKGEXT
119  
120  # We dont want to be bothered with scripts asking questions
121  PACKAGE_BUILDING=yes
122  export PACKAGE_BUILDING
123
124  # Lets start by cleaning up the string and getting it ready to parse
125  get_value_from_cfg_with_spaces installPackages
126  PACKAGES="${VAL}"
127  echo_log "Packages to install: `echo $PACKAGES | wc -w | awk '{print $1}'`"
128  for i in $PACKAGES
129  do
130    if ! get_package_name "${i}"
131    then
132      echo_log "Unable to locate package ${i}"
133      continue
134    fi
135
136    PKGNAME="${VAL}"
137
138    # Fetch package + deps, but skip if installing from local media
139    if [ "${INSTALLMEDIUM}" = "ftp" ] ; then
140      DEPFILE="${FSMNT}/${PKGTMPDIR}/.${PKGNAME}.deps"
141      rc_nohalt "touch ${DEPFILE}"
142      determine_package_dependencies "${PKGNAME}" "${DEPFILE}"
143      fetch_package_dependencies "${DEPFILE}" "${FSMNT}/${PKGTMPDIR}"
144    fi
145
146    # Set package location
147    case "${INSTALLMEDIUM}" in
148      usb|dvd|local) PKGPTH="${PKGTMPDIR}/All/${PKGNAME}" ;;
149                  *) PKGPTH="${PKGTMPDIR}/${PKGNAME}" ;;
150    esac
151
152    # See if we need to determine the package format we are working with
153    if [ -z "${PKGINFO}" ] ; then
154      tar tqf "${FSMNT}${PKGPTH}" '+MANIFEST' >/dev/null 2>/dev/null	
155      if [ $? -ne 0 ] ; then
156        PKGADD="pkg_add -C ${FSMNT}" 
157        PKGINFO="pkg_info" 
158      else
159        PKGADD="pkg -c ${FSMNT} add"
160        PKGINFO="pkg info"
161        bootstrap_pkgng
162      fi
163    fi
164
165    # If the package is not already installed, install it!
166    if ! run_chroot_cmd "${PKGINFO} -e ${PKGNAME}" >/dev/null 2>/dev/null
167    then
168      echo_log "Installing package: ${PKGNAME}"
169      rc_nohalt "${PKGADD} ${PKGPTH}"
170    fi
171
172    if [ "${INSTALLMEDIUM}" = "ftp" ] ; then
173      rc_nohalt "rm ${DEPFILE}"
174    fi
175
176  done
177
178  echo_log "Package installation complete!"
179
180  # Cleanup after ourselves
181  rc_halt "cd ${HERE}"
182  if [ "${INSTALLMEDIUM}" = "ftp" ] ; then
183    rc_halt "rm -rf ${FSMNT}${PKGTMPDIR}" >/dev/null 2>/dev/null
184  else
185    rc_halt "umount ${FSMNT}${PKGTMPDIR}" >/dev/null 2>/dev/null
186    rc_halt "rmdir ${FSMNT}${PKGTMPDIR}" >/dev/null 2>/dev/null
187  fi
188};
189