source: src-sh/pc-metapkgmanager/pc-metapkgmanager @ 6180a78

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

Add a new 'pkgdeps' target to pc-metapkgmanager, it will allow listing
the pkgng packages that a meta-package will install

  • Property mode set to 100644
File size: 12.6 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 mpkg1,mpkg2        -- Add the specified list of meta-packages
54  del mpkg1,mpkg2        -- Delete the specified list of meta-packages
55  list                   -- List the available meta-packages
56  list-installed         -- Only list the installed meta-packages
57  pkgdeps <mpkg>         -- List package dependancies for the specified meta-package
58  status <mpkg>          -- List the status of the specified meta-packages
59  --pkgset <pkgset>      -- Change default pkgset we are using
60
61EOF
62        exit 1
63}
64
65add_metapkgs() {
66        if [ -z "$1" ] ; then exit_err "No meta-pkg specified!" ; fi
67        if [ ! -e "${MPDIR}/${1}/ports-list" ] ; then exit_err "No such meta-pkg: $1" ; fi
68        local pkgName="`cat ${MPDIR}/$1/ports-list | cut -d ':' -f 1`"
69        if [ -z "$pkgName" ] ; then exit_err "No FreeBSD package specified for meta-pkg: ${1}" ; fi
70
71        _apkg=$1
72        echo "Installing Meta-Package: $_apkg ($pkgName)"
73
74        # If a pre-install script, run it now
75        if [ -e "${MPDIR}/${_apkg}/pre-install.sh" ] ; then
76          sh ${MPDIR}/${_apkg}/pre-install.sh >/dev/null 2>/dev/null
77        fi
78
79        # Lets check for any conflicts doing this install
80        check_pkg_conflicts "install -FUy $pkgName"
81        if [ $? -ne 0 ] ; then
82                exit 1
83        fi
84
85        # Don't need this anymore
86        unset EVENT_PIPE
87
88        # Time to run pkgng and let it install packages!
89        pkg install -yUf "$pkgName"
90
91        # Make sure the program appears fully installed now, if not set error
92        stat_metapkg ${_apkg}
93        if [ "$?" != "0" ] ; then _pkgStatus=1 ; fi
94
95        # Apply our PC-BSD specific xdg menu entry files
96        if [ -e "/usr/local/bin/pc-xdgutil" ] ; then
97          /usr/local/bin/pc-xdgutil updatemenu >>${LOGFILE} 2>>${LOGFILE}
98        fi
99
100        # Hack to ensure that we share cursors / icons between linux / FBSD apps
101        if [ ! -h "/compat/linux/usr/share/icons" ] ; then
102           rm -rf /compat/linux/usr/share/icons 2>/dev/null
103           ln -fs /usr/local/lib/X11/icons /compat/linux/usr/share/icons 2>/dev/null
104        fi
105        if [ ! -h "/compat/linux/usr/share/fonts" ] ; then
106           rm -rf /compat/linux/usr/share/fonts 2>/dev/null
107           ln -fs /usr/local/lib/X11/fonts /compat/linux/usr/share/fonts 2>/dev/null
108        fi
109
110        # If a post-install script, run it now
111        if [ -e "${MPDIR}/${_apkg}/post-install.sh" ] ; then
112          sh ${MPDIR}/${_apkg}/post-install.sh >/dev/null 2>/dev/null
113        fi
114
115        # Prune any port files we dont want
116        # Extract custom files
117        pc-extractoverlay ports
118
119        echo "Finished Meta-Package: $_apkg"
120       
121}
122
123# Delete specified meta-pkg, and packages which it installed that are not used elsewhere
124del_metapkgs() {
125        if [ -z "$1" ] ; then exit_err "No meta-pkg specified!" ; fi
126        if [ ! -e "${MPDIR}/${1}/ports-list" ] ; then exit_err "No such meta-pkg: $1" ; fi
127        local rmPkg="`cat ${MPDIR}/$1/ports-list | cut -d ':' -f 1`"
128        if [ -z "$rmPkg" ] ; then exit_err "No FreeBSD package specified for meta-pkg: ${1}" ; fi
129        _dpkg=$1
130        kPkgs=""
131
132        echo "Removing Meta-Package: $_dpkg"
133
134        # kPkgs is our list of packages which are required by other installed meta-pkgs
135        export kPkgs
136
137        # If a pre-remove script, run it now
138        if [ -e "${MPDIR}/${_dpkg}/pre-remove.sh" ] ; then
139          sh ${MPDIR}/${_dpkg}/pre-remove.sh >/dev/null 2>/dev/null
140        fi
141
142        # Make sure this pkg is installed
143        pkg info -e $rmPkg >/dev/null 2>/dev/null
144        if [ $? -ne 0 ] ; then
145                echo "Already uninstalled: ${rmPkg}" 
146                echo "Already uninstalled: ${rmPkg}" >>${LOGFILE}
147                return
148        fi
149
150        # confirm this package isn't required by any others
151        nbrequired=`pkg query "%?r" ${rmPkg}`
152        if [ $nbrequired -ne 0 ] ; then 
153                # Still in use, we will re-scan it at the end
154                echo "The package: ${rmPkg} is required by other packages: $nbrequired" 
155                echo "The package: ${rmPkg} is required by other packages: $nbrequired" >>${LOGFILE}
156                return
157        fi
158
159        # Now we use pkgng and remove it
160        echo "Removing: ${rmPkg}"
161        echo "Removing: ${rmPkg}" >>${LOGFILE}
162        pkg delete -y ${rmPkg} >>${LOGFILE} 2>>${LOGFILE}
163
164        # If the program is still fully installed, set status to error
165        stat_metapkg ${_dpkg}
166        if [ $? -eq 0 ] ; then _pkgStatus=1 ; fi
167
168        # If a post-remove script, run it now
169        if [ -e "${MPDIR}/${_dpkg}/post-remove.sh" ] ; then
170          sh ${MPDIR}/${_dpkg}/post-remove.sh >/dev/null 2>/dev/null
171        fi
172
173}
174
175# Function to list installed metapkgs
176list_installed_metapkgs() {
177        if [ ! -d "${MPDIR}" ] ; then exit_err "No available meta-pkg dir" ; fi
178
179        # Start listing each meta-pkg
180        for i in `find ${MPDIR}/* -type d`
181        do
182                # Is this package ignored on this arch?
183                if [ -e "${i}/ignore-arch" ] ; then
184                        if [ `cat ${i}/ignore-arch` = "$ARCH" ] ; then continue; fi
185                fi
186                MPNAME=`basename $i`
187                if [ ! -e "${MPDIR}/${MPNAME}/ports-list" ] ; then continue ; fi
188
189                stat_metapkg "$MPNAME" >/dev/null 2>/dev/null
190                if [ $? -eq 0 ] ; then
191                   if [ -z "$installed" ] ; then
192                     installed="$MPNAME"
193                   else
194                     installed="$installed $MPNAME"
195                   fi
196                fi
197        done
198        echo "$installed"
199}
200
201# List the package deps for the specified meta-pkg
202list_pkgdeps() {
203        if [ -z "$1" ] ; then exit_err "No meta-pkg specified!" ; fi
204        if [ ! -e "${MPDIR}/${1}/ports-list" ] ; then exit_err "No such meta-pkg: $1" ; fi
205        cat ${MPDIR}/$1/ports-list | cut -d ':' -f 1
206        exit 0
207}
208
209# Function to list available metapkgs
210list_metapkgs() {
211        if [ ! -d "${MPDIR}" ] ; then exit_err "No available meta-pkg dir" ; fi
212
213        # Start listing each meta-pkg
214        for i in `find ${MPDIR}/* -type d`
215        do
216                # Is this package ignored on this arch?
217                if [ -e "${i}/ignore-arch" ] ; then
218                        if [ `cat ${i}/ignore-arch` = "$ARCH" ] ; then continue; fi
219                fi
220
221                if [ -e "${i}/pkg-desc" ] ; then
222
223                        echo "Meta Package: `basename ${i}`"
224                        echo "-------------------------------------"
225                        echo "Description: `cat ${i}/pkg-desc`"
226                        if [ -e "${i}/pkg-icon.png" ] ; then
227                                echo "Icon: ${i}/pkg-icon.png"
228                        fi
229                        if [ -e "${i}/pkg-parent" ] ; then
230                                echo "Parent: `cat ${i}/pkg-parent`"
231                        fi
232                        if [ -e "${i}/desktop" ] ; then
233                                echo "Desktop: YES"
234                        else
235                                echo "Desktop: NO"
236                        fi
237                        echo " "
238                        if [ -e "${i}/ports-list" ] ; then
239                                echo "Required Packages:"
240                                cat ${i}/ports-list | cut -d ':' -f 1
241                        else
242                                echo "Category Entry"
243                        fi
244                        echo " "
245                fi
246        done
247
248}
249
250# Check on a meta-pkg, see if its installed, partially installed, or not.
251stat_metapkg() {
252        if [ -z "$1" ] ; then exit_err "No meta-pkg specified!" ; fi
253        if [ ! -e "${MPDIR}/${1}/ports-list" ] ; then exit_err "No such meta-pkg: $1" ; fi
254        local myPkg="`cat ${MPDIR}/$1/ports-list | cut -d ':' -f 1`"
255        if [ -z "$myPkg" ] ; then exit_err "No FreeBSD package specified for meta-pkg: ${1}" ; fi
256        _mpkg=$1
257
258        # Parse pkg db to see if pkgs are installed
259        pkg query "%n" | grep -q "^$myPkg"
260        if [ $? -eq 0 ] ; then
261                echo "The meta-pkg $_mpkg is installed"
262                return 0
263        else
264                echo "The meta-pkg $_mpkg is not installed"
265                return 255
266        fi
267
268}
269
270# Read through comma delimited list of meta-pkgs
271parse_metapkgs() {
272
273        if [ "$2" != "add" -a "$2" != "del" ] ; then
274                exit_err "Internal error, must use add/del for parse_metapkgs"
275        fi
276
277        create_logfile
278
279        get_num_pkgs "$1"
280        echo "Pending Meta-Package changes: $VAL"
281        echo "Pending Meta-Package changes: $VAL" >>${LOGFILE}
282
283        # Set the package add exit status to default of 0
284        _pkgStatus=0
285
286        local list
287        list=`echo "$1" | sed 's|,| |g'`       
288        for z in $list
289        do
290                if [ "$2" = "add" ] ; then add_metapkgs "$z" "$3" ; fi
291                if [ "$2" = "del" ] ; then del_metapkgs "$z" ; fi
292        done
293
294        # Update the mime data
295        xdg-update-defaults >/dev/null 2>/dev/null
296
297        echo "Meta-Package changes finished!"
298        exit "$_pkgStatus"
299
300}
301
302
303# Get the number of packages we are working on
304get_num_pkgs() {
305        VAL=`echo $1 | sed 's|,| |g' | wc -w | tr -d ' '`
306}
307
308# Create the logfile
309create_logfile() {
310        if [ -e "${LOGFILE}" ]; then
311                # Rotate the log file if over 5 MB
312                if [ `du -m ${LOGFILE} | awk '{print $1}'` -gt 5 ]; then
313                        rm ${LOGFILE}
314                fi
315        fi
316        touch ${LOGFILE}
317        chmod 666 ${LOGFILE}
318}
319
320do_pkg_conflicts()
321{
322   fullopts="`echo $@ | sed 's|check-conflict||g'`"
323
324   echo "install -FUy $fullopts" > /tmp/err
325   # Lets check for any conflicts doing this install
326   check_pkg_conflicts "install -FUy $fullopts"
327   exit $?
328}
329
330intercept_pkg_dl()
331{
332   # Time to run pkgng and let it do its thing
333   pkg $@
334   result=$?
335
336   # Set PKG_CACHEDIR
337   PKG_CACHEDIR="`pkg config PKG_CACHEDIR`"
338
339   # Nobody likes a litter bug
340   if [ $result -eq 0 -a -d "${PKG_CACHEDIR}/All" ] ; then
341      echo -e "Cleaning up cache files..\c"
342      rm -rf "${PKG_CACHEDIR}/All"
343      echo -e "Done"
344   fi
345
346   # Make sure we run extract-overlay again
347   pc-extractoverlay ports >/dev/null 2>/dev/null
348   
349   exit $result
350}
351
352get_file_dl()
353{
354   if [ "$2" = "-o" ] ; then
355      dlOut="$3"
356      dlPath="$4"
357   else
358      dlOut="`basename $2`"
359      dlPath="$2"
360   fi
361   get_file_from_mirrors "$dlPath" "$dlOut" "iso"
362   exit $?
363}
364
365# Parse the flags we are sending over to pkg
366# will intercept the install / upgrade flags
367# and use our internal function to download
368# in a much faster method ;)
369do_pc-pkg()
370{
371   case $1 in
372         install) intercept_pkg_dl ${@} ;;
373  check-conflict) do_pkg_conflicts ${@} ;;
374         getfile) get_file_dl ${@} ;;
375               *) pkg ${@} 
376                  exit $?
377                  ;;
378   esac 
379}
380
381# Are we running in pc-pkg mode?
382if [ `basename $0` = "pc-pkg" ] ; then
383   do_pc-pkg $@
384   exit 0
385fi
386
387# Unset some vars
388_pkgflags=""
389PKGUPDATES=""
390
391# The default PKGSET
392PKGSET="pcbsd"
393
394# Check if we have a different dataset specified in pcbsd.conf
395PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
396_pkgChk="`sed -n 's/PCBSD_METAPKGSET: //p' ${PCBSD_ETCCONF} 2>/dev/null`"
397if [ -n "${_pkgChk}" ] ; then PKGSET="$_pkgChk" ; fi
398MPDIR="${DBDIR}/${PKGSET}"
399TMPDIR="/usr/local/tmp"
400
401if [ $# -eq 0 ]; then display_usage; fi
402
403# Parse ye olde cli flags
404while [ $# -gt 0 ]; do
405  case "$1" in
406       pkgdeps) list_pkgdeps "$2" ; exit 0 ;;
407          list) list_metapkgs ; exit 0 ;;
408list-installed) list_installed_metapkgs ; exit 0 ;;
409       add) parse_metapkgs "$2" "add" "$3" ; exit 0 ;;
410       del) parse_metapkgs "$2" "del" ; exit 0 ;;
411    status) stat_metapkg "$2" ; exit 0 ;;
412  --chroot) if [ -z "$2" ] ; then display_usage ; fi 
413            _chroot="$2" 
414            if [ ! -e "${_chroot}/bin/sh" ] ; then
415              echo "Invalid chroot dir: ${_chroot}"
416              exit 1
417            fi
418            _pkgflags="-C ${_chroot}"
419            _chrootcmd="chroot ${_chroot}"
420            _chroottag="--chroot ${_chroot}"
421
422            # Check for an alternative default pkgset in this chroot
423            PCBSD_ETCCONF="${_chroot}/usr/local/etc/pcbsd.conf"
424            _pkgChk="`sed -n 's/PCBSD_METAPKGSET: //p' ${PCBSD_ETCCONF} 2>/dev/null`"
425            if [ -n "${_pkgChk}" ] ; then PKGSET="$_pkgChk" ; fi
426            MPDIR="${DBDIR}/${PKGSET}"
427            shift
428            ;;
429  --pkgset) if [ -z "$2" ] ; then display_usage ; fi 
430            PKGSET="$2" 
431            if [ ! -d "${DBDIR}/$PKGSET" ] ; then
432              echo "No such package set $PKGSET"
433              exit 1
434            fi
435            MPDIR="${DBDIR}/${PKGSET}"
436            shift ;;
437         *) if [ -z "$1" ] ; then
438              shift
439            else
440              display_usage
441            fi 
442            ;;
443  esac
444  shift
445done
446
447exit 0
448
Note: See TracBrowser for help on using the repository browser.