source: src-sh/pc-metapkgmanager/pc-metapkgmanager @ 7004a51

releng/10.0releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since 7004a51 was 7004a51, checked in by Kris Moore <kris@…>, 10 months ago

Add ability to pc-metapkgmanager to build a "list" of installed meta-pkgs

  • Property mode set to 100644
File size: 12.2 KB
Line 
1#!/bin/sh
2#
3# Copyright 2013 Kris Moore (iXsystems)
4# All rights reserved
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted providing that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26
27# Source our functions
28. /usr/local/share/pcbsd/scripts/functions.sh
29
30# Define some defaults
31DBDIR="/usr/local/share/pcbsd/metaset"
32LOGFILE="/tmp/.pc-metapkgmanager.log"
33FTP_PASSIVE_MODE="YES" ; export FTP_PASSIVE_MODE
34PACKAGESUFFIX=".txz" ; export PACKAGESUFFIX
35ARCH="`uname -m`"
36
37# Start by sourcing /etc/profile
38# This grabs any HTTP_ / FTP_ PROXY variables
39. /etc/profile
40
41# Fix some pkgs bugging us with license questions
42PACKAGE_BUILDING=yes
43export PACKAGE_BUILDING
44
45# Trigger File for Tray Application
46TRIGGERFILE="/tmp/.sysupdatetraytrigger"
47
48display_usage() {
49        cat <<EOF
50usage: `basename $0` [options]
51   
52Options:
53  add pkg1,pkg2          -- Add the specified list of meta-packages
54  del pkg1,pkg2          -- Delete the specified list of meta-packages
55  list                   -- List the available meta-packages
56  list-installed         -- Only list the installed meta-packages
57  status <pkg>           -- List the status of the specified meta-packages
58  --pkgset <pkgset>      -- Change default pkgset we are using
59
60EOF
61        exit 1
62}
63
64add_metapkgs() {
65        if [ -z "$1" ] ; then exit_err "No meta-pkg specified!" ; fi
66        if [ ! -e "${MPDIR}/${1}/ports-list" ] ; then exit_err "No such meta-pkg: $1" ; fi
67        local pkgName="`cat ${MPDIR}/$1/ports-list | cut -d ':' -f 1`"
68        if [ -z "$pkgName" ] ; then exit_err "No FreeBSD package specified for meta-pkg: ${1}" ; fi
69
70        _apkg=$1
71        echo "Installing Meta-Package: $_apkg ($pkgName)"
72
73        # If a pre-install script, run it now
74        if [ -e "${MPDIR}/${_apkg}/pre-install.sh" ] ; then
75          sh ${MPDIR}/${_apkg}/pre-install.sh >/dev/null 2>/dev/null
76        fi
77
78        # Lets check for any conflicts doing this install
79        check_pkg_conflicts "install -FUy $pkgName"
80        if [ $? -ne 0 ] ; then
81                exit 1
82        fi
83
84        # Don't need this anymore
85        unset EVENT_PIPE
86
87        # Time to run pkgng and let it install packages!
88        pkg install -yUf "$pkgName"
89
90        # Make sure the program appears fully installed now, if not set error
91        stat_metapkg ${_apkg}
92        if [ "$?" != "0" ] ; then _pkgStatus=1 ; fi
93
94        # Apply our PC-BSD specific xdg menu entry files
95        if [ -e "/usr/local/bin/pc-xdgutil" ] ; then
96          /usr/local/bin/pc-xdgutil updatemenu >>${LOGFILE} 2>>${LOGFILE}
97        fi
98
99        # Hack to ensure that we share cursors / icons between linux / FBSD apps
100        if [ ! -h "/compat/linux/usr/share/icons" ] ; then
101           rm -rf /compat/linux/usr/share/icons 2>/dev/null
102           ln -fs /usr/local/lib/X11/icons /compat/linux/usr/share/icons 2>/dev/null
103        fi
104        if [ ! -h "/compat/linux/usr/share/fonts" ] ; then
105           rm -rf /compat/linux/usr/share/fonts 2>/dev/null
106           ln -fs /usr/local/lib/X11/fonts /compat/linux/usr/share/fonts 2>/dev/null
107        fi
108
109        # If a post-install script, run it now
110        if [ -e "${MPDIR}/${_apkg}/post-install.sh" ] ; then
111          sh ${MPDIR}/${_apkg}/post-install.sh >/dev/null 2>/dev/null
112        fi
113
114        # Prune any port files we dont want
115        # Extract custom files
116        pc-extractoverlay ports
117
118        echo "Finished Meta-Package: $_apkg"
119       
120}
121
122# Delete specified meta-pkg, and packages which it installed that are not used elsewhere
123del_metapkgs() {
124        if [ -z "$1" ] ; then exit_err "No meta-pkg specified!" ; fi
125        if [ ! -e "${MPDIR}/${1}/ports-list" ] ; then exit_err "No such meta-pkg: $1" ; fi
126        local rmPkg="`cat ${MPDIR}/$1/ports-list | cut -d ':' -f 1`"
127        if [ -z "$rmPkg" ] ; then exit_err "No FreeBSD package specified for meta-pkg: ${1}" ; fi
128        _dpkg=$1
129        kPkgs=""
130
131        echo "Removing Meta-Package: $_dpkg"
132
133        # kPkgs is our list of packages which are required by other installed meta-pkgs
134        export kPkgs
135
136        # If a pre-remove script, run it now
137        if [ -e "${MPDIR}/${_dpkg}/pre-remove.sh" ] ; then
138          sh ${MPDIR}/${_dpkg}/pre-remove.sh >/dev/null 2>/dev/null
139        fi
140
141        # Make sure this pkg is installed
142        pkg info -e $rmPkg >/dev/null 2>/dev/null
143        if [ $? -ne 0 ] ; then
144                echo "Already uninstalled: ${rmPkg}" 
145                echo "Already uninstalled: ${rmPkg}" >>${LOGFILE}
146                return
147        fi
148
149        # confirm this package isn't required by any others
150        nbrequired=`pkg query "%?r" ${rmPkg}`
151        if [ $nbrequired -ne 0 ] ; then 
152                # Still in use, we will re-scan it at the end
153                echo "The package: ${rmPkg} is required by other packages: $nbrequired" 
154                echo "The package: ${rmPkg} is required by other packages: $nbrequired" >>${LOGFILE}
155                return
156        fi
157
158        # Now we use pkgng and remove it
159        echo "Removing: ${rmPkg}"
160        echo "Removing: ${rmPkg}" >>${LOGFILE}
161        pkg delete -y ${rmPkg} >>${LOGFILE} 2>>${LOGFILE}
162
163        # If the program is still fully installed, set status to error
164        stat_metapkg ${_dpkg}
165        if [ $? -eq 0 ] ; then _pkgStatus=1 ; fi
166
167        # If a post-remove script, run it now
168        if [ -e "${MPDIR}/${_dpkg}/post-remove.sh" ] ; then
169          sh ${MPDIR}/${_dpkg}/post-remove.sh >/dev/null 2>/dev/null
170        fi
171
172}
173
174# Function to list installed metapkgs
175list_installed_metapkgs() {
176        if [ ! -d "${MPDIR}" ] ; then exit_err "No available meta-pkg dir" ; fi
177
178        # Start listing each meta-pkg
179        for i in `find ${MPDIR}/* -type d`
180        do
181                # Is this package ignored on this arch?
182                if [ -e "${i}/ignore-arch" ] ; then
183                        if [ `cat ${i}/ignore-arch` = "$ARCH" ] ; then continue; fi
184                fi
185                MPNAME=`basename $i`
186                if [ ! -e "${MPDIR}/${MPNAME}/ports-list" ] ; then continue ; fi
187
188                stat_metapkg "$MPNAME" >/dev/null 2>/dev/null
189                if [ $? -eq 0 ] ; then
190                   if [ -z "$installed" ] ; then
191                     installed="$MPNAME"
192                   else
193                     installed="$installed $MPNAME"
194                   fi
195                fi
196        done
197        echo "$installed"
198}
199
200
201# Function to list available metapkgs
202list_metapkgs() {
203        if [ ! -d "${MPDIR}" ] ; then exit_err "No available meta-pkg dir" ; fi
204
205        # Start listing each meta-pkg
206        for i in `find ${MPDIR}/* -type d`
207        do
208                # Is this package ignored on this arch?
209                if [ -e "${i}/ignore-arch" ] ; then
210                        if [ `cat ${i}/ignore-arch` = "$ARCH" ] ; then continue; fi
211                fi
212
213                if [ -e "${i}/pkg-desc" ] ; then
214
215                        echo "Meta Package: `basename ${i}`"
216                        echo "-------------------------------------"
217                        echo "Description: `cat ${i}/pkg-desc`"
218                        if [ -e "${i}/pkg-icon.png" ] ; then
219                                echo "Icon: ${i}/pkg-icon.png"
220                        fi
221                        if [ -e "${i}/pkg-parent" ] ; then
222                                echo "Parent: `cat ${i}/pkg-parent`"
223                        fi
224                        if [ -e "${i}/desktop" ] ; then
225                                echo "Desktop: YES"
226                        else
227                                echo "Desktop: NO"
228                        fi
229                        echo " "
230                        if [ -e "${i}/ports-list" ] ; then
231                                echo "Required Packages:"
232                                cat ${i}/ports-list | cut -d ':' -f 1
233                        else
234                                echo "Category Entry"
235                        fi
236                        echo " "
237                fi
238        done
239
240}
241
242# Check on a meta-pkg, see if its installed, partially installed, or not.
243stat_metapkg() {
244        if [ -z "$1" ] ; then exit_err "No meta-pkg specified!" ; fi
245        if [ ! -e "${MPDIR}/${1}/ports-list" ] ; then exit_err "No such meta-pkg: $1" ; fi
246        local myPkg="`cat ${MPDIR}/$1/ports-list | cut -d ':' -f 1`"
247        if [ -z "$myPkg" ] ; then exit_err "No FreeBSD package specified for meta-pkg: ${1}" ; fi
248        _mpkg=$1
249
250        # Parse pkg db to see if pkgs are installed
251        pkg query "%n" | grep -q "^$myPkg"
252        if [ $? -eq 0 ] ; then
253                echo "The meta-pkg $_mpkg is installed"
254                return 0
255        else
256                echo "The meta-pkg $_mpkg is not installed"
257                return 255
258        fi
259
260}
261
262# Read through comma delimited list of meta-pkgs
263parse_metapkgs() {
264
265        if [ "$2" != "add" -a "$2" != "del" ] ; then
266                exit_err "Internal error, must use add/del for parse_metapkgs"
267        fi
268
269        create_logfile
270
271        get_num_pkgs "$1"
272        echo "Pending Meta-Package changes: $VAL"
273        echo "Pending Meta-Package changes: $VAL" >>${LOGFILE}
274
275        # Set the package add exit status to default of 0
276        _pkgStatus=0
277
278        local list
279        list=`echo "$1" | sed 's|,| |g'`       
280        for z in $list
281        do
282                if [ "$2" = "add" ] ; then add_metapkgs "$z" "$3" ; fi
283                if [ "$2" = "del" ] ; then del_metapkgs "$z" ; fi
284        done
285
286        # Update the mime data
287        xdg-update-defaults >/dev/null 2>/dev/null
288
289        echo "Meta-Package changes finished!"
290        exit "$_pkgStatus"
291
292}
293
294
295# Get the number of packages we are working on
296get_num_pkgs() {
297        VAL=`echo $1 | sed 's|,| |g' | wc -w | tr -d ' '`
298}
299
300# Create the logfile
301create_logfile() {
302        if [ -e "${LOGFILE}" ]; then
303                # Rotate the log file if over 5 MB
304                if [ `du -m ${LOGFILE} | awk '{print $1}'` -gt 5 ]; then
305                        rm ${LOGFILE}
306                fi
307        fi
308        touch ${LOGFILE}
309        chmod 666 ${LOGFILE}
310}
311
312do_pkg_conflicts()
313{
314   fullopts="`echo $@ | sed 's|check-conflict||g'`"
315
316   echo "install -FUy $fullopts" > /tmp/err
317   # Lets check for any conflicts doing this install
318   check_pkg_conflicts "install -FUy $fullopts"
319   exit $?
320}
321
322intercept_pkg_dl()
323{
324   # Time to run pkgng and let it do its thing
325   pkg $@
326   result=$?
327
328   # Set PKG_CACHEDIR
329   PKG_CACHEDIR="`pkg config PKG_CACHEDIR`"
330
331   # Nobody likes a litter bug
332   if [ $result -eq 0 -a -d "${PKG_CACHEDIR}/All" ] ; then
333      echo -e "Cleaning up cache files..\c"
334      rm -rf "${PKG_CACHEDIR}/All"
335      echo -e "Done"
336   fi
337
338   # Make sure we run extract-overlay again
339   pc-extractoverlay ports >/dev/null 2>/dev/null
340   
341   exit $result
342}
343
344get_file_dl()
345{
346   if [ "$2" = "-o" ] ; then
347      dlOut="$3"
348      dlPath="$4"
349   else
350      dlOut="`basename $2`"
351      dlPath="$2"
352   fi
353   get_file_from_mirrors "$dlPath" "$dlOut" "iso"
354   exit $?
355}
356
357# Parse the flags we are sending over to pkg
358# will intercept the install / upgrade flags
359# and use our internal function to download
360# in a much faster method ;)
361do_pc-pkg()
362{
363   case $1 in
364         install) intercept_pkg_dl ${@} ;;
365  check-conflict) do_pkg_conflicts ${@} ;;
366         getfile) get_file_dl ${@} ;;
367               *) pkg ${@} 
368                  exit $?
369                  ;;
370   esac 
371}
372
373# Are we running in pc-pkg mode?
374if [ `basename $0` = "pc-pkg" ] ; then
375   do_pc-pkg $@
376   exit 0
377fi
378
379# Unset some vars
380_pkgflags=""
381PKGUPDATES=""
382
383# The default PKGSET
384PKGSET="pcbsd"
385
386# Check if we have a different dataset specified in pcbsd.conf
387PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
388_pkgChk="`sed -n 's/PCBSD_METAPKGSET: //p' ${PCBSD_ETCCONF} 2>/dev/null`"
389if [ -n "${_pkgChk}" ] ; then PKGSET="$_pkgChk" ; fi
390MPDIR="${DBDIR}/${PKGSET}"
391TMPDIR="/usr/local/tmp"
392
393if [ $# -eq 0 ]; then display_usage; fi
394
395# Parse ye olde cli flags
396while [ $# -gt 0 ]; do
397  case "$1" in
398          list) list_metapkgs ; exit 0 ;;
399list-installed) list_installed_metapkgs ; exit 0 ;;
400       add) parse_metapkgs "$2" "add" "$3" ; exit 0 ;;
401       del) parse_metapkgs "$2" "del" ; exit 0 ;;
402    status) stat_metapkg "$2" ; exit 0 ;;
403  --chroot) if [ -z "$2" ] ; then display_usage ; fi 
404            _chroot="$2" 
405            if [ ! -e "${_chroot}/bin/sh" ] ; then
406              echo "Invalid chroot dir: ${_chroot}"
407              exit 1
408            fi
409            _pkgflags="-C ${_chroot}"
410            _chrootcmd="chroot ${_chroot}"
411            _chroottag="--chroot ${_chroot}"
412
413            # Check for an alternative default pkgset in this chroot
414            PCBSD_ETCCONF="${_chroot}/usr/local/etc/pcbsd.conf"
415            _pkgChk="`sed -n 's/PCBSD_METAPKGSET: //p' ${PCBSD_ETCCONF} 2>/dev/null`"
416            if [ -n "${_pkgChk}" ] ; then PKGSET="$_pkgChk" ; fi
417            MPDIR="${DBDIR}/${PKGSET}"
418            shift
419            ;;
420  --pkgset) if [ -z "$2" ] ; then display_usage ; fi 
421            PKGSET="$2" 
422            if [ ! -d "${DBDIR}/$PKGSET" ] ; then
423              echo "No such package set $PKGSET"
424              exit 1
425            fi
426            MPDIR="${DBDIR}/${PKGSET}"
427            shift ;;
428         *) if [ -z "$1" ] ; then
429              shift
430            else
431              display_usage
432            fi 
433            ;;
434  esac
435  shift
436done
437
438exit 0
439
Note: See TracBrowser for help on using the repository browser.