Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/distrib/sets * Give regpkg the ability to create binary sysp...



details:   https://anonhg.NetBSD.org/src/rev/ed8572923b22
branches:  trunk
changeset: 586862:ed8572923b22
user:      apb <apb%NetBSD.org@localhost>
date:      Wed Jan 04 14:14:35 2006 +0000

description:
* Give regpkg the ability to create binary syspkg packages (*.tgz files).
  The new "-t binpkgdir" option requests this action.
* Make it pay attention to DESTDIR.
* Make it work for unprivileged builds using METALOG.
* Add "force" and "update" modes.
* Add "quiet" mode.  There was already a "verbose" mode.
* Add several new command line args in support of the above.
* Make much more use of shell functions.
* Replace the old way of choosing syspkg version numbers.
  The new way gives numbers derived from concatenating the OS
  version [from osrelease.sh or $(uname -r)], a "tiny" version [from
  distrib/sets/versions, default 0], and a date [from RCS time stamps or
  file system time stamps].
* Add @blddep lines to the PLIST (in addition to the @pkgdep lines
  that were previously added).
* Use host tools such as pax, cksum, and db, to do more or less the
  same work that was previously done by pkg_create (which is not a host
  tool).  No longer attempt to use pkg_create.

Reviewed by agc

diffstat:

 distrib/sets/regpkg |  1104 ++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 960 insertions(+), 144 deletions(-)

diffs (truncated from 1153 to 300 lines):

diff -r 2e550cd29378 -r ed8572923b22 distrib/sets/regpkg
--- a/distrib/sets/regpkg       Wed Jan 04 13:57:04 2006 +0000
+++ b/distrib/sets/regpkg       Wed Jan 04 14:14:35 2006 +0000
@@ -1,6 +1,6 @@
 #! /bin/sh
 #
-# $NetBSD: regpkg,v 1.8 2006/01/03 18:31:09 apb Exp $
+# $NetBSD: regpkg,v 1.9 2006/01/04 14:14:35 apb Exp $
 #
 # Copyright (c) 2003 Alistair G. Crooks.  All rights reserved.
 #
@@ -33,50 +33,258 @@
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 
-# Usage: regpkg set pkgname
-
-rundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/"
-
-SYSPKGROOT="${PKG_DBDIR:-/var/db/pkg}"
-case "${SYSPKG_DBDIR}" in
-"")    ;;
-*)     SYSPKGROOT="${SYSPKG_DBDIR}" ;;
-esac
-
-PLIST="/tmp/.PLIST.$$"
+# Usage: regpkg [options] set pkgname
+#
+# Registers a syspkg in the database directory,
+# and optionally creates a binary package.
+#
+# Options:
+#   -q         Quiet.
+#   -v         Verbose.
+#   -f         Force.
+#   -m         Ignore errors from missing files.
+#   -u         Update.
+#   -c         Use cached information from ${BUILD_INFO_CACHE}.
+#   -d destdir Sets DESTDIR.
+#   -t binpkgdir Create a binary package (in *.tgz format) in the
+#              specified directory.  Without this option, a binary
+#              package is not created.
+#   -M metalog Use the specified metalog file to override file
+#              or directory attributes when creating a binary package.
+#   -N etcdir  Use the specified directory for passwd and group files.
+#
+# When -f is set:  If the desired syspkg already exists, it is overwritten.
+# When -u is set:  If the desired syspkg already exists, it might be
+#              overwritten or left alone, depending on whether it's older
+#              or newer than the files that belong to the syspkg.
+# When neither -u nor -f are set:  It's an error for the desired syspkg
+#              to already exist.
 
-verbose=""
-while [ $# -gt 2 ]; do
-       case "$1" in
-       -v)     verbose="$1" ;;
-       *)      break ;;
-       esac
-       shift
-done
+prog="${0##*/}"
+toppid=$$
+rundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/"
+. "${rundir}/sets.subr"
+
+bomb()
+{
+       #echo "${prog}: bomb: start, toppid=${toppid} \$\$=$$"
+       kill ${toppid}          # in case we were invoked from a subshell
+       #echo "${prog}: bomb: killed ${toppid}"
+       exit 1
+}
 
-if [ $# -ne 2 ]; then
-       echo "Usage: regpkg set pkgname"
-       exit 1
+# A literal newline
+nl='
+'
+# A literal tab
+tab='  '
+
+# Prefixes for error messages, warnings, and important informational
+# messages.
+ERROR="${prog}: ERROR: "
+WARNING="${prog}: WARNING: "
+NOTE="${prog}: NOTE: "
+ERRWARN="${ERROR}"     # may be changed by "-f" (force) command line flag
+ERRWARNNOTE="${ERROR}" # may be changed by "-u" (update) command line flag
+
+#
+# All temporary files will go in ${SCRATCH}, which will be deleted on
+# exit.
+#
+SCRATCH="$( ${MKTEMP} -d "/var/tmp/${0##*/}.XXXXXX" )"
+if [ $? -ne 0 -o \! -d "${SCRATCH}" ]; then
+       echo >&2 "Could not create scratch directory."
+       bomb
 fi
 
-pkgset="$1"
-
-pkg="$2"
-
-case "${verbose}" in
--v)    echo "Making PLIST for \"${pkgset}\" set and \"${pkg}\" package" ;;
-esac
+#
+# cleanup() always deletes the SCRATCH directory, and might also
+# delete other files or directories.
+#
+es=0
+cleanup_must_delete_binpkgfile=false
+cleanup_must_delete_dbsubdir=false
+cleanup ()
+{
+       trap - 0
+       #echo "${prog}: cleanup start"
+       if ${cleanup_must_delete_binpkgfile:-false} && [ -e "${binpkgfile}" ]
+       then
+               echo >&2 "${prog}: deleting partially-created ${binpkgfile}"
+               rm -f "${binpkgfile}"
+       fi
+       if ${cleanup_must_delete_dbsubdir:-false} \
+          && [ -e "${SYSPKG_DB_SUBDIR}" ]
+       then
+               echo >&2 "${prog}: deleting partially-created ${SYSPKG_DB_SUBDIR}"
+               rm -rf "${SYSPKG_DB_SUBDIR}"
+       fi
+       rm -rf "${SCRATCH}"
+       #echo "${prog}: cleanup done, exit ${es}"
+       exit ${es}
+}
+trap 'es=128; cleanup' 1 2 3 13 15     # HUP INT QUIT PIPE TERM
+trap 'es=$?; cleanup' 0                # EXIT
 
-# create the skeleton PLIST from the pkgset description
-"${rundir}/makeplist" "${pkgset}" "${pkg}" > "${PLIST}"
+#
+# Parse command line args.
+#
+verbose=false
+verbosity=0
+quiet=false
+force=false
+update=false
+allowmissing=false
+DESTDIR="${DESTDIR}"
+binpkgdir=""
+metalog=""
+etcdir=""
+SYSPKG_DB_TOPDIR=""
+pkgset=""
+pkg=""
+parse_args ()
+{
+       while [ $# -gt 2 ]; do
+               case "$1" in
+               -q)     quiet=true ; verbose=false ;;
+               -v)     verbose=true ; quiet=false
+                       verbosity=$(( ${verbosity} + 1 ))
+                       ;;
+               -f)     force=true ;;
+               -u)     update=true ;;
+               -m)     allowmissing=true ;;
+               -c)     # The -c option is ignored.  The BUILD_INFO_CACHE
+                       # environment variable is used instead.
+                       ;;
+               -d)     DESTDIR="$2" ; shift ;;
+               -d*)    DESTDIR="${1#-?}" ;;
+               -t)     binpkgdir="$2" ; shift ;;
+               -t*)    binpkgdir="${1#-?}" ;;
+               -M)     metalog="$2" ; shift ;;
+               -M*)    metalog="${1#-?}" ;;
+               -N)     etcdir="$2" ; shift ;;
+               -N*)    etcdir="${1#-?}" ;;
+               *)      break ;;
+               esac
+               shift
+       done
+       if ${force}; then
+               ERRWARN="${WARNING}"
+       else
+               ERRWARN="${ERROR}"
+       fi
+       if ${update}; then
+               ERRWARNNOTE="${NOTE}"
+       else
+               ERRWARNNOTE="${ERRWARN}"
+       fi
+       DESTDIR="${DESTDIR%/}" # delete trailing "/" if any
+       if [ \! -n "${etcdir}" ]; then
+               etcdir="${DESTDIR}/etc"
+       fi
+       if [ -n "${binpkgdir}" -a \! -d "${binpkgdir}" ]; then
+               echo >&2 "${ERROR}binary pkg directory ${binpkgdir} does not exist"
+               bomb
+       fi
+       #
+       # SYSPKG_DB_TOPDIR is the top level directory for registering
+       # syspkgs.  It defaults to ${DESTDIR}/var/db/syspkg, but can be
+       # overridden by environment variables SYSPKG_DBDIR or PKG_DBDIR.
+       #
+       # Note that this corresponds to the default value of PKG_DBDIR
+       # set in .../distrib/syspkg/mk/bsd.syspkg.mk.
+       # 
+       SYSPKG_DB_TOPDIR="${SYSPKG_DBDIR:-${PKG_DBDIR:-${DESTDIR}/var/db/syspkg}}"
+
+       if [ $# -ne 2 ]; then
+               echo "Usage: regpkg [options] set pkgname"
+               bomb
+       fi
+
+       pkgset="$1"
+       pkg="$2"
+}
 
-# create the pkg tiny version
-case "${SYSPKG_DATES}" in
-"")    tinyvers="$(${AWK} '$1 ~ '/"${pkg}"/' { print $2 }' "${rundir}/versions")"
-       case "${tinyvers}" in
-       "")     tinyvers=0
-               ;;
-       esac
+#
+# make_PLIST() creates a skeleton PLIST from the pkgset description.
+#
+# The result is stored in the file ${PLIST}.
+#
+PLIST="${SCRATCH}/PLIST"
+make_PLIST ()
+{
+       if ${verbose} ; then
+               echo "Making PLIST for \"${pkg}\" package (part of ${pkgset} set)"
+       fi
+       prefix="${DESTDIR:-/}"
+       realprefix=/
+       ${HOST_SH} "${rundir}/makeplist" -p "${prefix}" -I "${realprefix}" \
+               "${pkgset}" "${pkg}" \
+               >"${PLIST}" 2>"${SCRATCH}/makeplist-errors"
+       if ${EGREP} -v '^DEBUG:' "${SCRATCH}/makeplist-errors" ; then
+               # "find" invoked from makeplist sometimes reports
+               # errors about missing files or directories, and
+               # makeplist ignores the errors.  Catch them here.
+               echo >&2 "${ERROR}makeplist reported errors for ${pkg}:"
+               cat >&2 "${SCRATCH}/makeplist-errors"
+               echo >&2 "${ERROR}see above for errors from makeplist"
+               if ${allowmissing}; then
+                       echo >&2 "${prog}: ${NOTE}: ignoring above errors, due to '-m' option."
+               else
+                       ${force} || bomb
+               fi
+       fi
+}
+
+#
+# init_allfiles() converts the PLIST (which contains relative filenames)
+# into a list of absolute filenames.  Directories are excluded from the
+# result.
+# 
+# The result is stored in the variable ${allfiles}.
+#
+allfiles=''
+init_allfiles ()
+{
+       [ -f "${PLIST}" ] || make_PLIST
+       allfiles="$( ${AWK} '
+               BEGIN { destdir = "'"${DESTDIR%/}"'" }
+               /^@cwd/ { prefix = $2; next }
+               /^@dirrm/ { next }
+               { printf("%s%s%s\n", destdir, prefix, $0) }' "${PLIST}" )"
+}
+
+#
+# init_newestfile() finds the newest file (most recent mtime).
+#
+# The result is stored in the variable ${newestfile}.
+#
+newestfile=''
+init_newestfile ()
+{
+       [ -s "${allfiles}" ] || init_allfiles
+       # We assume no shell special characters in ${allfiles},
+       # and spaces only between file names, not inside file names.
+       # This should be safe, because it has no no user-specified parts.
+       newestfile="$( ${LS} -1dt ${allfiles} | ${SED} '1q' )"
+}
+
+#
+# Various ways of getting parts of the syspkg version number:
+#
+# get_osvers() - get the OS version number from osrelease.sh or $(uname -r),
+#              return it in ${osvers}, and set ${method}.
+# get_tinyvers() - get the tiny version number from the "versions" file,
+#              and return it in ${tinyvers}.  Does not set ${method}.
+# get_newest_rcsid_date() - get the newest RCS date,
+#              and return it in ${newest}.  Does not set ${method}.
+# get_newest_mtime_date() - get the newest file modification date,
+#              and return it in ${newest}.  Does not set ${method}.



Home | Main Index | Thread Index | Old Index