pkgsrc-Changes-HG archive

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

[pkgsrc/trunk]: pkgsrc/mk Use reference counts to properly account for the cr...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/1d3652432ea9
branches:  trunk
changeset: 488330:1d3652432ea9
user:      jlam <jlam%pkgsrc.org@localhost>
date:      Fri Jan 28 06:30:58 2005 +0000

description:
Use reference counts to properly account for the creation and removal
of directories needed for the proper functioning of each package.

The +INSTALL script unpacks a +DIRS script that adds and removes
directories.  The +DIRS script entirely encapsulates the directory
creation and removal, and completely replaces the code in the
mk/install/install and mk/install/deinstall templates that handled
{MAKE,OWN}_DIRS and {MAKE,OWN}_DIRS_PERMS.

The +DIRS script is meant to be executed from within the package
meta-data directory, e.g.  /var/db/pkg/<pkgname>.  It's usage is:

        ./+DIRS ADD|REMOVE|CHECK-ADD|CHECK-REMOVE

The ADD and REMOVE actions cause the necessary directories to be added
or removed from the system.  The CHECK-ADD and CHECK-REMOVE actions
print out informative messages prompting the user to either create or
remove some necessary directories.

The behaviour of "ADD" is such that if the directory already exists
on the system and is not already ref-counted, then that directory is
marked as "pre-existing".  On "REMOVE", pre-existing directories are
left untouched on the filesystem.

At any time, the root user can sanity-check the directories needed by
packages by invoking all of the +DIRS scripts with the "CHECK-ADD"
action.  If there are missing directories, then invoking all of the
+DIRS scripts with the "ADD" action will ensure that any missing
directories are created.

The reference counts database is stored in ${PKG_DBDIR}/.refcount.
The reference counts related to directories managed by the +DIRS script
are stored in ${PKG_DBDIR}/.refcount/dirs.  If the directory reference
counts database is removed, then invoking all of the +DIRS scripts
with the "ADD" action will reconstruct the database; however, directories
may be marked as being pre-existing, so they won't be removed at
package de-installation (although a message will be displayed informing
the user that those directories can be removed).

diffstat:

 mk/bsd.pkg.install.mk |   67 +++++++++++++++-
 mk/install/deinstall  |   90 +--------------------
 mk/install/dirs       |  206 ++++++++++++++++++++++++++++++++++++++++++++++++++
 mk/install/header     |   11 +-
 mk/install/install    |  105 +------------------------
 5 files changed, 282 insertions(+), 197 deletions(-)

diffs (truncated from 609 to 300 lines):

diff -r e7fbee09b698 -r 1d3652432ea9 mk/bsd.pkg.install.mk
--- a/mk/bsd.pkg.install.mk     Fri Jan 28 02:29:36 2005 +0000
+++ b/mk/bsd.pkg.install.mk     Fri Jan 28 06:30:58 2005 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: bsd.pkg.install.mk,v 1.72 2005/01/26 23:15:03 jlam Exp $
+# $NetBSD: bsd.pkg.install.mk,v 1.73 2005/01/28 06:30:58 jlam Exp $
 #
 # This Makefile fragment is included by bsd.pkg.mk to use the common
 # INSTALL/DEINSTALL scripts.  To use this Makefile fragment, simply:
@@ -78,6 +78,13 @@
 FILES_SUBST+=          PKGBASE=${PKGBASE}
 FILES_SUBST+=          PKG_INSTALLATION_TYPE=${PKG_INSTALLATION_TYPE}
 
+# Database directory for reference-counted package objects.  Subdirectories
+# represent different classes of package objects, e.g. dirs, users,
+# group, etc.
+#
+_PKG_REFCOUNT_DBDIR=   ${PKG_DBDIR}/.refcount
+FILES_SUBST+=          PKG_REFCOUNT_DBDIR=${_PKG_REFCOUNT_DBDIR:Q}
+
 # PKG_USERS represents the users to create for the package.  It is a
 #      space-separated list of elements of the form
 #
@@ -208,10 +215,59 @@
 MAKE_DIRS_PERMS?=      # empty
 OWN_DIRS?=             # empty
 OWN_DIRS_PERMS?=       # empty
-FILES_SUBST+=          MAKE_DIRS=${MAKE_DIRS:Q}
-FILES_SUBST+=          MAKE_DIRS_PERMS=${MAKE_DIRS_PERMS:Q}
-FILES_SUBST+=          OWN_DIRS=${OWN_DIRS:Q}
-FILES_SUBST+=          OWN_DIRS_PERMS=${OWN_DIRS_PERMS:Q}
+
+INSTALL_DIRS_FILE=     ${WRKDIR}/.install-dirs
+INSTALL_UNPACK_TMPL+=  ${INSTALL_DIRS_FILE}
+
+${INSTALL_DIRS_FILE}: ../../mk/install/dirs
+       ${_PKG_SILENT}${_PKG_DEBUG}{                                    \
+       ${ECHO} "# start of install-dirs";                              \
+       ${ECHO} "#";                                                    \
+       ${ECHO} "# Generate a +DIRS script that reference counts directories"; \
+       ${ECHO} "# that are required for the proper functioning of the"; \
+       ${ECHO} "# package.";                                           \
+       ${ECHO} "#";                                                    \
+       ${ECHO} "case \$${STAGE} in";                                   \
+       ${ECHO} "PRE-INSTALL)";                                         \
+       ${ECHO} "       \$${CAT} > ./+DIRS << 'EOF_DIRS'";              \
+       ${SED} ${FILES_SUBST_SED} ../../mk/install/dirs;                \
+       ${ECHO} "";                                                     \
+       case "${CONF_FILES}${CONF_FILES_PERMS}${SUPPORT_FILES}${SUPPORT_FILES_PERMS}" in \
+       "")     ;;                                                      \
+       *)      ${ECHO} "# DIR: ${PKG_SYSCONFDIR} m" ;;                 \
+       esac;                                                           \
+       case "${RCD_SCRIPTS}" in                                        \
+       "")     ;;                                                      \
+       *)      ${ECHO} "# DIR: ${RCD_SCRIPTS_DIR} m" ;;                \
+       esac;                                                           \
+       eval set -- ${MAKE_DIRS} ;                                      \
+       while ${TEST} $$# -gt 0; do                                     \
+               dir="$$1"; shift;                                       \
+               ${ECHO} "# DIR: $$dir m";                               \
+       done;                                                           \
+       eval set -- ${OWN_DIRS} ;                                       \
+       while ${TEST} $$# -gt 0; do                                     \
+               dir="$$1"; shift;                                       \
+               ${ECHO} "# DIR: $$dir mo";                              \
+       done;                                                           \
+       eval set -- ${MAKE_DIRS_PERMS} ;                                \
+       while ${TEST} $$# -gt 0; do                                     \
+               dir="$$1"; owner="$$2"; group="$$3"; mode="$$4";        \
+               shift; shift; shift; shift;                             \
+               ${ECHO} "# DIR: $$dir m $$owner $$group $$mode";        \
+       done;                                                           \
+       eval set -- ${OWN_DIRS_PERMS} ;                                 \
+       while ${TEST} $$# -gt 0; do                                     \
+               dir="$$1"; owner="$$2"; group="$$3"; mode="$$4";        \
+               shift; shift; shift; shift;                             \
+               ${ECHO} "# DIR: $$dir mo $$owner $$group $$mode";       \
+       done;                                                           \
+       ${ECHO} "EOF_DIRS";                                             \
+       ${ECHO} "       \$${CHMOD} +x ./+DIRS";                         \
+       ${ECHO} "       ;;";                                            \
+       ${ECHO} "esac";                                                 \
+       } > ${.TARGET}.tmp;                                             \
+       ${MV} -f ${.TARGET}.tmp ${.TARGET}
 
 # PKG_CREATE_USERGROUP indicates whether the INSTALL script should
 #      automatically add any needed users/groups to the system using
@@ -298,6 +354,7 @@
 FILES_SUBST_SED=       ${FILES_SUBST:S/=/@!/:S/$/!g/:S/^/ -e s!@/}
 
 INSTALL_SCRIPTS_ENV=   PKG_PREFIX=${PREFIX}
+INSTALL_SCRIPTS_ENV+=  PKG_METADATA_DIR=${_PKG_DBDIR}/${PKGNAME}
 
 .PHONY: pre-install-script post-install-script
 
diff -r e7fbee09b698 -r 1d3652432ea9 mk/install/deinstall
--- a/mk/install/deinstall      Fri Jan 28 02:29:36 2005 +0000
+++ b/mk/install/deinstall      Fri Jan 28 06:30:58 2005 +0000
@@ -1,6 +1,6 @@
 # start of deinstall
 #
-# $NetBSD: deinstall,v 1.29 2004/10/11 22:04:19 reed Exp $
+# $NetBSD: deinstall,v 1.30 2005/01/28 06:30:59 jlam Exp $
 
 eval set -- ${PKG_USERS}
 for userset; do
@@ -45,34 +45,6 @@
        VIEW_FILES="${VIEW_FILES} \"${file}\""
 done
 
-eval set -- ${PKG_SYSCONFDIR} ${RCD_SCRIPTS_DIR} ${MAKE_DIRS}
-for dir; do
-       ALL_MAKE_DIRS="${ALL_MAKE_DIRS} \"${dir}\""
-done
-eval set -- ${MAKE_DIRS_PERMS}
-while [ $# -gt 0 ]; do
-       dir="$1"; owner="$2"; group="$3"; mode="$4"
-       shift; shift; shift; shift
-       ALL_MAKE_DIRS="${ALL_MAKE_DIRS} \"${dir}\""
-done
-eval set -- ${ALL_MAKE_DIRS} ${OWN_DIRS}
-for dir; do
-       ALL_DIRS="${ALL_DIRS} \"${dir}\""
-done
-eval set -- ${OWN_DIRS_PERMS}
-while [ $# -gt 0 ]; do
-       dir="$1"; owner="$2"; group="$3"; mode="$4"
-       shift; shift; shift; shift
-       ALL_DIRS="${ALL_DIRS} \"${dir}\""
-done
-ALL_DIRS=`
-       ( eval set -- ${ALL_DIRS}
-         for dir; do
-               ${ECHO} "\"${dir}\""
-         done
-       ) | ${SORT} -r
-`
-
 case ${STAGE} in
 VIEW-DEINSTALL)
        if [ "${_PKG_CONFIG}" = "YES" -a -n "${VIEW_FILES}" ]; then
@@ -140,51 +112,9 @@
                ${RMDIR} -p `${DIRNAME} ${PKG_SYSCONFDIR}` 2>/dev/null || ${TRUE}
        fi
 
-       existing_dirs=''
-       eval set -- ${ALL_DIRS}
-       for dir; do
-               if [ "${_PKG_CONFIG}" = "YES" ]; then
-                       if [ -f "${dir}/.pkgsrc" ]; then
-                               dirowner=`${HEAD} -1 "${dir}/.pkgsrc"`
-                               if [ "${dirowner}" = "${PKGBASE}" ]; then
-                                       ${RM} -f "${dir}/.pkgsrc"
-                                       ${RMDIR} -p "${dir}" 2>/dev/null || ${TRUE}
-                               fi
-                       fi
-                       is_make_dir=`                                   \
-                               eval set -- ${ALL_MAKE_DIRS};           \
-                               is_make_dir=0;                          \
-                               for make_dir; do                        \
-                                       case "${make_dir}" in           \
-                                       ${dir}) is_make_dir=1; break ;; \
-                                       esac;                           \
-                               done;                                   \
-                               ${ECHO} ${is_make_dir}                  \
-                       `
-                       if [ ${is_make_dir} -eq 0 -a -d "${dir}" ]; then
-                               existing_dirs="${existing_dirs} \"${dir}\""
-                       fi
-               else
-                       case "${dir}" in
-                       ${PKG_PREFIX}/*)
-                               ${RMDIR} -p "${dir}" 2>/dev/null || ${TRUE}
-                               ;;
-                       esac
-                       case "${dir}" in
-                       #
-                       # Don't bother the admin about the following dirs
-                       # if they still exist.
-                       #
-                       ${PKG_SYSCONFBASE}|${RCD_SCRIPTS_DIR})
-                               ;;
-                       *)      
-                               if [ -d "${dir}" ]; then
-                                       existing_dirs="${existing_dirs} \"${dir}\""
-                               fi
-                               ;;
-                       esac
-               fi
-       done
+       case ${_PKG_CONFIG} in
+       YES)    ${TEST} -x ./+DIRS && ./+DIRS REMOVE ${PKG_METADATA_DIR} ;;
+       esac
 
        if [ -n "${ALL_USERS}" -o -n "${ALL_GROUPS}" -o                 \
             -n "${modified_files}" -o -n "${existing_dirs}" ]; then
@@ -225,17 +155,6 @@
                                ${ECHO} "       ${file}"
                        done
                fi
-               if [ -n "${existing_dirs}" ]; then
-                       ${CAT} << EOF
-
-  * the following directories:
-
-EOF
-                       eval set -- ${existing_dirs}
-                       for dir; do
-                               ${ECHO} "       ${dir}"
-                       done
-               fi
                if [ -n "${RCD_SCRIPTS}" ]; then
                        ${CAT} << EOF
 
@@ -247,6 +166,7 @@
 ===========================================================================
 EOF
        fi
+       ${TEST} -x ./+DIRS && ./+DIRS CHECK-REMOVE
        ;;
 esac
 
diff -r e7fbee09b698 -r 1d3652432ea9 mk/install/dirs
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/mk/install/dirs   Fri Jan 28 06:30:58 2005 +0000
@@ -0,0 +1,206 @@
+#!@SH@
+#
+# +DIRS - reference-counted directory management script
+#
+# Usage: ./+DIRS ADD|REMOVE [metadatadir]
+#        ./+DIRS CHECK-ADD|CHECK-REMOVE
+#
+# This script supports two actions, ADD and REMOVE, that will add or
+# remove the directories needed by the package associated with
+# <metadatadir>.  The CHECK-ADD action will check whether any directories
+# needed by the package are missing, and print an informative message
+# noting those directories.  The CHECK-REMOVE action will check whether
+# any directories needed by the package still exist, and print an
+# informative message noting those directories.  The CHECK-ADD and
+# CHECK-REMOVE actions return non-zero if they detect either missing
+# or existing directories, respectively.
+#
+# Lines starting with "# DIR: " are data read by this script that
+# name the directories that this package requires to exist to function
+# correctly, e.g.
+#
+#      # DIR: /etc/foo m
+#      # DIR: /var/log/foo/tmp mo foo-user foo-group 0700
+#
+# The second field in each DIRS entry is a set of flags with the following
+# meaning:
+#
+#      m       create (make) the directory when ADDing
+#      o       directory is owned by the package
+#
+CAT="@CAT@"
+CHGRP="@CHGRP@"
+CHMOD="@CHMOD@"
+CHOWN="@CHOWN@"
+ECHO="@ECHO@"
+GREP="@GREP@"
+MKDIR="@MKDIR@"
+MV="@MV@"
+PWD_CMD="@PWD_CMD@"
+RM="@RM@"
+RMDIR="@RMDIR@"
+SED="@SED@"
+SORT="@SORT@"
+TEST="@TEST@"
+TRUE="@TRUE@"
+
+SELF=$0
+ACTION=$1
+PKG_METADATA_DIR="${2-`${PWD_CMD}`}"
+PKG_REFCOUNT_DBDIR="@PKG_REFCOUNT_DBDIR@"
+: ${PKGNAME=${PKG_METADATA_DIR##*/}}
+
+PKG_REFCOUNT_DIRS_DBDIR="${PKG_REFCOUNT_DBDIR}/dirs"
+
+exitcode=0
+case $ACTION in
+ADD)
+       ${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -u |
+       while read dir d_flags d_user d_group d_mode; do
+               case $dir in
+               ""|[!/]*)       continue ;;
+               esac
+               case $d_flags in
+               *m*)    ;;
+               *)      continue ;;
+               esac
+               shadow_dir="${PKG_REFCOUNT_DIRS_DBDIR}$dir"
+               perms="$shadow_dir/+PERMISSIONS"
+               preexist="$shadow_dir/+PREEXISTING"
+               token="$shadow_dir/${PKGNAME}"
+               if ${TEST} ! -d "$shadow_dir"; then
+                       ${MKDIR} $shadow_dir
+                       ${TEST} -d "$dir" &&
+                               ${ECHO} "${PKGNAME}" > $preexist



Home | Main Index | Thread Index | Old Index