diff options
-rw-r--r-- | postgresql.eselect | 262 |
1 files changed, 129 insertions, 133 deletions
diff --git a/postgresql.eselect b/postgresql.eselect index 7ff9b83..b8ecbe1 100644 --- a/postgresql.eselect +++ b/postgresql.eselect @@ -1,4 +1,4 @@ -# Copyright 1999-2013 Gentoo Foundation +# Copyright 1999-2017 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: $ @@ -6,12 +6,11 @@ inherit config multilib DESCRIPTION="Manage active PostgreSQL client applications and libraries" MAINTAINER="pgsql-bugs@gentoo.org" -VERSION="1.3" +VERSION="2.0" -# Global Data +# We do a lot of things in /usr and it's a bit of a pain to write this +# constantly. USR_PATH="${EROOT%/}/usr" -ETC_PATH="${EROOT%/}/etc/eselect/postgresql" -ENV_FILE="${EROOT%/}/etc/env.d/50postgresql" # This list of files/directories are the symbolic link targets that need to be # created when a slot is set. @@ -28,11 +27,11 @@ INCLUDE_TARGETS=( ) active_slot() { - # ${USR_PATH}/share/postgresql is a symlink. See if it's there, then - # find out where it links to + # ${USR_PATH}/share/postgresql is a symlink to the active + # slot. See if it's there, then find out where it links to. if [[ -h "${USR_PATH}/share/postgresql" ]] ; then canonicalise "${USR_PATH}/share/postgresql" | \ - sed 's|.*postgresql-\([1-9][0-9.]*\)|\1|' + sed -re 's#.*([1-9][0-9.]+)$#\1#' else echo "(none)" fi @@ -86,7 +85,7 @@ linker() { local findings local rel_source - findings=$(finder "${source_dir}" ${pattern}) + findings=$(finder "${source_dir}" "${pattern}") for link_source in ${findings} ; do local link_target="${target_dir%/}/$(basename ${link_source})${suffix}" @@ -109,9 +108,9 @@ get_slots() { local slot local found_slots - for slot in $(find "${USR_PATH}/$(lib_dir)/" -maxdepth 1 -type d \ - -regex '.*/postgresql-[1-9][0-9]*\.*[0-9]*' | \ - sed -re 's#.*([1-9][0-9]*\.*[0-9]*)$#\1#' | sort -n) + for slot in $(find "${USR_PATH}/$(lib_dir)/" \ + -mindepth 1 -maxdepth 1 -type d -name 'postgresql-*' | \ + sed -re 's#.*([1-9][0-9.]+)$#\1#' | sort -n) do # Check that pg_config exists for this slot, otherwise we have # a false positive. @@ -186,24 +185,21 @@ describe_set() { } do_set() { - local SLOT=$1 + local slot=$1 - if [[ ! -d ${USR_PATH}/$(lib_dir)/postgresql-${SLOT} ]] ; then + if [[ ! -d ${USR_PATH}/$(lib_dir)/postgresql-${slot} ]] ; then die -q "Not a valid slot." fi # If there's an active slot, unset that one first - if [[ "$(active_slot)" == "${SLOT}" ]] ; then - echo $(highlight "No work to do.") - echo "If you think the links need to be reset, use the reset action." - return 0 - elif [[ "$(active_slot)" != "(none)" ]] ; then - echo -ne "\tRemoving old links..." - do_unset $(active_slot) + local active_slot=$(active_slot) + if [[ "${active_slot}" != "(none)" ]] ; then + echo -ne "Unsetting ${active_slot} as default..." + do_unset ${active_slot} echo "done." fi - echo "Setting ${SLOT} as the default installation..." + echo "Setting ${slot} as the default..." echo -ne "\tGenerating new links..." # Sources for header files @@ -212,12 +208,12 @@ do_set() { # If you change this list, you must change the INCLUDE_TARGETS list, # too. And, they must be listed in the same order. local include_sources=( - "${USR_PATH}"/include/postgresql-${SLOT} - "${USR_PATH}"/include/postgresql-${SLOT}/libpq-fe.h - "${USR_PATH}"/include/postgresql-${SLOT}/pg_config_ext.h - "${USR_PATH}"/include/postgresql-${SLOT}/pg_config_manual.h - "${USR_PATH}"/include/postgresql-${SLOT}/libpq - "${USR_PATH}"/include/postgresql-${SLOT}/postgres_ext.h + "${USR_PATH}"/include/postgresql-${slot} + "${USR_PATH}"/include/postgresql-${slot}/libpq-fe.h + "${USR_PATH}"/include/postgresql-${slot}/pg_config_ext.h + "${USR_PATH}"/include/postgresql-${slot}/pg_config_manual.h + "${USR_PATH}"/include/postgresql-${slot}/libpq + "${USR_PATH}"/include/postgresql-${slot}/postgres_ext.h ) # The linker function cannot accommodate this special purpose. @@ -227,38 +223,49 @@ do_set() { # Some headers are present only in specific versions of PostgreSQL [[ -e ${include_sources[$i]} ]] || continue - # Create relative links so that they work both here and inside the new + # Create relative links so that they work both here and inside a new # root if $ROOT is not "/" rel_source=$(relative_name "${include_sources[$i]}" "$(dirname "${INCLUDE_TARGETS[$i]}")") ln -s "$rel_source" "${INCLUDE_TARGETS[$i]}" || \ - die -q "Unable to create link!" + die -q "Unable to create link! $rel_source -> ${INCLUDE_TARGETS[$i]}" done # Link modules to /usr/lib{,32,64}/ local x for x in $(list_libdirs) ; do - if [[ -d ${USR_PATH}/${x}/postgresql-${SLOT}/${x} ]] ; then + if [[ -d "${USR_PATH}/${x}/postgresql-${slot}/${x}" ]] ; then # 'linker' function doesn't work for linking directories. # Default lib path - create a relative link - ln -s "postgresql-${SLOT}/${x}" "${USR_PATH}/${x}/postgresql" + ln -s "postgresql-${slot}/${x}" "${USR_PATH}/${x}/postgresql" # Linker works for files - linker "${USR_PATH}/${x}/postgresql-${SLOT}/${x}/" \ + linker "${USR_PATH}/${x}/postgresql-${slot}/${x}/" \ "-name lib*" "${USR_PATH}/${x}" fi done # Link binaries to /usr/bin/ - linker "${USR_PATH}/$(lib_dir)/postgresql-${SLOT}/bin/" \ - "-type f" "${USR_PATH}/bin" + linker "${USR_PATH}/$(lib_dir)/postgresql-${slot}/bin/" \ + "" "${USR_PATH}/bin" + + # Link pkg-config metadata files + linker "${USR_PATH}/$(lib_dir)/postgresql-${slot}/$(lib_dir)/pkgconfig/" \ + "" "${USR_PATH}/share/pkgconfig/" + + # Link man pages + local mandir mansec + for mandir in "${USR_PATH}"/share/postgresql-${slot}/man/man{1,3,7} ; do + mansec=$(basename "${mandir}") + linker "${mandir}" "" "${USR_PATH}/share/man/${mansec}" + done # Default share path - use a relative link here by just specifying the # base name - ln -s "postgresql-${SLOT}" "${USR_PATH}/share/postgresql" + ln -s "postgresql-${slot}" "${USR_PATH}/share/postgresql" echo "done." - echo "Setting ${SLOT} as default was successful!" + echo "Setting ${slot} as default was successful!" } ### Unset Action ### @@ -268,35 +275,58 @@ describe_unset() { # Undo everything done by do_set(). do_unset() { - local SLOT=$1 - if [[ ${SLOT} != $(active_slot) ]] ; then + local slot=$1 + if [[ ${slot} != $(active_slot) ]] ; then echo "Slot already inactive; no work to do." return 0 fi - local l - for l in ${INCLUDE_TARGETS[@]} "${USR_PATH}/share/postgresql" ; do - [[ -h ${l} ]] && rm -f "${l}" + # Start with some known locations that are, or will contain, symlinks. + local paths=( + "${INCLUDE_TARGETS[@]}" + "${USR_PATH}"/share/man/man{1,3,7} + "${USR_PATH}/share/postgresql" + "${USR_PATH}/bin" + "${USR_PATH}/share/pkgconfig" + ) - # Check if include target still exists - [[ -e ${l} ]] && \ - die -q "The target '${l}' exists and could not be removed!" - done + local lib + for lib in $(list_libdirs) ; do + # If $libdir is a symlink, it will point to a real lib directory that + # will be or has been added in this loop. + [[ -h "${USR_PATH}/${lib}" ]] && continue - for l in $(find "${USR_PATH}/bin" -type l) ; do - if [[ $(realpath ${l} | grep -c postgresql) -ge 1 ]] ; then - rm "${l}" + # If the $libdir/postgresql symlink exists, then there are certainly + # others within that same directory that must be cleaned up. + if [[ -h "${USR_PATH}/${lib}/postgresql" ]] ; then + paths+=( "${USR_PATH}/${lib}" ) fi done - for x in $(list_libdirs) ; do - if [[ -h "${USR_PATH}/${x}/postgresql" ]] ; then - for l in $(find "${USR_PATH}/${x}" -type l) ; do - if [[ $(realpath ${l} | grep -c postgresql) -ge 1 ]] ; then - rm "${l}" - fi - done + local l path + for path in "${paths[@]}" ; do + # If path is a link that belongs to the slot in question, it can be + # removed without invoking find. + if [[ -h "${path}" && \ + $(canonicalise "${path}") == *postgresql-${slot}* ]] ; then + rm "${path}" || write_warning_msg "Couldn't remove: ${path}" + continue fi + + # If path is a real directory, symlinks need to be found within it. + for l in $(find "${path}" -mindepth 1 -maxdepth 1 -type l) ; do + # Skip the slot specific links (e.g., psql96) in /usr/bin and + # /usr/share/man as they're managed by their ebuilds + [[ ${l} == ${USR_PATH}/bin/*${slot/.} ]] && continue + [[ ${l} == ${USR_PATH}/share/man/man?/*${slot/.}* ]] && continue + + # Get the file path that the link is pointing to. If it has the + # string "postgresql-${slot}" somewhere in it, then it's a link that + # needs to be removed. + if [[ $(canonicalise "${l}") == *postgresql-${slot}* ]] ; then + rm "${l}" || write_warning_msg "Couldn't remove: ${l}" + fi + done done } @@ -306,10 +336,10 @@ describe_reset() { } do_reset() { - local SLOT=$(active_slot) - [[ ${SLOT} = "(none)" ]] && die -q "No active slot to reset." - do_unset ${SLOT} - do_set ${SLOT} + local slot=$(active_slot) + [[ ${slot} == "(none)" ]] && die -q "No active slot to reset." + do_unset ${slot} + do_set ${slot} } ### Update Action ### @@ -318,99 +348,65 @@ describe_update() { } do_update() { - local slot=$(active_slot) - - ## CLEAN UP ## + ## ANTIQUITY CLEAN UP ## # # Older versions of this module generated state and environment files of # some sort or another. They're useless now and are just a waste of space. - # Remove environment files that have been generated by the ebuilds - rm -f "${ENV_FILE}"-* - if [[ -d ${ETC_PATH} ]] ; then + # Environment files that have been generated by older ebuilds and + # previous versions of this module serve no purpose now. + rm -f "${EROOT%/}"/etc/env.d/50postgresql* + + local etc_path="${EROOT%/}/etc/eselect/postgresql" + if [[ -d ${etc_path} ]] ; then # Remove some files outright as they're entirely useless now. - # ${ETC_PATH}/active: Contents was the active slot (e.g., 9.5) - # ${ETC_PATH}/service: Told the initscript which slot to start + # ${etc_path}/active: Contents was the active slot (e.g., + # 9.5), or it was a symlink to another file that was then + # canonicalised and parsed to get the active slot + # ${etc_path}/service: Told the initscript which slot to + # start. We now have separate scripts for each slot + # ${etc_path}/active.links*: Contained a list of symlinks + # created. We now search the known directories for the + # symlinks as only this module manage them. local f - for f in "${ETC_PATH}/active" "${ETC_PATH}/service" ; do - [[ -e "${f}" ]] && rm -f "${f}" - done - - local active_link_file - for active_link_file in "${ETC_PATH}"/active.links* ; do - local active_links=($(<"${active_link_file}")) - for (( i=0; $i < ${#active_links[@]}; i++ )) ; do - [[ -h "${ROOT%/}/${active_links[$i]}" ]] && \ - rm -f "${ROOT%/}/${active_links[$i]}" - [[ -e "${ROOT%/}/${active_links[$i]}" ]] && \ - die -q "The target '${active_links[$i]}' still exists and could not be removed!" - done - - rm "${active_link_file}" || \ - write_warning_msg "Can't remove '${active_link_file}'" + for f in "${etc_path}"/active* "${etc_path}/service" ; do + if [[ -e "${f}" ]] ; then + rm "${f}" || write_warning_msg "Can't remove: '${f}'" + fi done local unused_files - unused_file=$(find "${ETC_PATH}" -type f -not -name '.keep*') + unused_file=( $(find "${etc_path}" -type f -not -name '.keep*') ) if [[ -n "${unused_file[@]}" ]] ; then write_warning_msg "You have unused files that should be removed:" for f in ${unused_file[@]} ; do write_warning_msg $f done else - echo "It's should be safe for you to remove '${ETC_PATH}'" + echo "It should be safe for you to remove '${etc_path}'" fi fi + ## End Antiquity Clean Up - ## End Clean Up - + local active_slot=$(active_slot) local slots=($(get_slots)) - local index=${#slots[@]} - - if [[ ${index} -eq 0 ]] ; then - write_warning_msg "No slots found!" - rm -f "${ENV_FILE}" - do_action env update &> /dev/null - return 0 - fi - # Reset, otherwise set the highest slot available. - if [[ ${slots[@]} =~ ${slot} ]] ; then - do_reset ${slot} + if [[ ${slots[@]} =~ ${active_slot} ]] ; then + # If active_slot is in the slots list, do a reset as the installation + # may have changed. + do_reset + elif [[ ${#slots[@]} -ne 0 ]] ; then + # If $slots is not empty but ${active_slot} is set, the active_slot + # must have been unmerged and its links need to be cleaned before... + [[ ${active_slot} != "(none)" ]] && do_unset ${active_slot} + + # Setting the highest slot available. + do_set ${slots[-1]} + elif [[ ${active_slot} != "(none)" ]] ; then + # If slots is empty, but active_slot still has a value, an unset must + # happen as the links are now pointing to nothing. + do_unset ${active_slot} else - # best_version doesn't work here as pkg_postrm runs before the world - # file is updated, thereby returning a false positive. - do_set ${slots[$index-1]} + echo "Apparently, I have nothing to do." fi - - # Update paths to libs and man pages - local ldpath - local pcpath - local x - for x in $(list_libdirs) ; do - if [[ -h ${USR_PATH}/${x}/postgresql ]] ; then - ldpath+="${USR_PATH}/${x}/postgresql:" - pcpath+="${USR_PATH}/${x}/postgresql/pkgconfig:" - fi - done - ldpath="${ldpath%:}" - pcdpath="${pcpath%:}" - local manpath="${USR_PATH}/share/postgresql/man/" - while [[ $[--index] -gt -1 ]] ; do - local curslot="${slots[$index]}" - for x in $(list_libdirs) ; do - local lib_path="${USR_PATH}/${x}/postgresql-${curslot}/${x}/" - local pkg_path="${lib_path}/pkgconfig" - [[ -d ${lib_path} ]] && ldpath+=":${lib_path}" - [[ -d ${pkg_path} ]] && pcpath+=":${pcpath}" - done - local tmp_manpath="${USR_PATH}/share/postgresql-${curslot}/man/" - [[ -d ${tmp_manpath} ]] && manpath+=":${tmp_manpath}" - echo "done." - done - - store_config "${ENV_FILE}" LDPATH "${ldpath}" - store_config "${ENV_FILE}" MANPATH "${manpath}" - store_config "${ENV_FILE}" PKG_CONFIG_PATH "${pcpath}" - do_action env update &> /dev/null } |