# Copyright 1999-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: $ inherit config multilib output package-manager path-manipulation DESCRIPTION="Manage active PostgreSQL client applications and libraries" MAINTAINER="pgsql-bugs@gentoo.org" SVN_DATE='$Date: $' VERSION="1.0.4" # Global Data B_PATH="${EROOT%/}/usr" E_PATH="${EROOT%/}/etc/eselect/postgresql" ENV_FILE="${EROOT%/}/etc/env.d/50postgresql" if [ -r ${E_PATH}/active -a -n ${E_PATH}/active ] ; then ACTIVE_SLOT=$(<${E_PATH}/active) else ACTIVE_SLOT="(none)" fi LIB_LIST=$(list_libdirs) if [[ ${LIB_LIST} =~ .*lib64.* && "$(ls -d ${B_PATH}/lib64/postgresql-*/lib)" != "" ]] ; then LIBDIR="lib64" elif [[ ${LIB_LIST} =~ .*lib32.* && "$(ls -d ${B_PATH}/lib32/postgresql-*/lib)" != "" ]] ; then LIBDIR="lib32" else LIBDIR="lib" fi ### Linker Function ### # Takes three arguments: # - Full source path (e.g. /usr/lib/postgresql-9.0/lib/lib*.{a,so}) # - Full target directory path (e.g. /usr/bin) # - Suffix (Optional) (e.g 84 to make /usr/bin/psql84) linker() { local source_dir=$1 local target_dir=$2 local suffix=$3 local link_source for link_source in $(eval ls ${source_dir} 2> /dev/null) ; do local link_target="${target_dir%/}/$(basename ${link_source})${suffix}" # For good measure, remove target before creating the symlink [ -h ${link_target} ] && rm -f ${link_target} [ -e ${link_target} ] && die -q "The target '${link_target}' still exists and could not be removed!" ln -s ${link_source} ${link_target} || die -q "Unable to create link!" echo ${link_target} >> ${E_PATH}/active.links${suffix} done } ### Unlinker Function ### # Takes one argument: # - Full path to active links file (e.g. /etc/eselect/postgresql/active.links) unlinker() { local active_link_file=$1 if [ -r ${active_link_file} ] ; then local active_links=($(<${active_link_file})) for (( i=0; $i < ${#active_links[@]}; i++ )) ; do [ -h ${active_links[$i]} ] && rm -f ${active_links[$i]} [ -e ${active_links[$i]} ] && die -q "The target '${active_links[$i]}' still exists and could not be removed!" done rm -f ${active_link_file} fi } ### Get Slots Function ### # Find all available slots in the preferred LIBDIR and return them. get_slots() { echo $(ls -dv ${B_PATH}/${LIBDIR}/postgresql-* 2> /dev/null | sed -re 's#^.+-##') } ### List Action ### describe_list() { echo "List available PostgreSQL slots." } do_list() { write_list_start "Available PostgreSQL Slots" if $(is_output_mode brief) ; then echo $(get_slots) else local slot for slot in $(get_slots) ; do local postgres_ebuilds="" local src for src in ${E_PATH}/slots/${slot}/{server,service,base,docs} ; do [ -r ${src} ] && source ${src} done case "${slot}" in "${ACTIVE_SLOT}" ) write_kv_list_entry "$(highlight_marker ${slot})" "${postgres_ebuilds//postgresql-/}";; * ) write_kv_list_entry "${slot}" "${postgres_ebuilds//postgresql-/}";; esac done [ -z "${postgres_ebuilds}" ] && write_warning_msg "No slots available." fi } ### Show Action ### describe_show() { echo "Show which slot is currently active." } do_show() { echo ${ACTIVE_SLOT} } ### Show Service Action ### # Here for backwards compatibility with ebuilds describe_show-service() { echo "Deprecated. For ebuild use; returns no useful information." } do_show-service() { echo 1 } ### Set Action ### describe_set() { echo "Create symbolic links for PostgreSQL libraries and applications." } do_set() { local SLOT=$1 if [ ! -d ${B_PATH}/${LIBDIR}/postgresql-${SLOT} ] ; then die -q "Not a valid slot." fi echo "Setting ${SLOT} as the default installation..." # Remove the active links to start a fresh list echo -ne "\tRemoving old links..." unlinker ${E_PATH}/active.links echo "done." echo -ne "\tGenerating new links..." # Sources and targets for header files local sources=( ${B_PATH}/include/postgresql-${SLOT} ${B_PATH}/include/postgresql-${SLOT}/libpq-fe.h ${B_PATH}/include/postgresql-${SLOT}/pg_config_manual.h ${B_PATH}/include/postgresql-${SLOT}/libpq ${B_PATH}/include/postgresql-${SLOT}/postgres_ext.h ) local targets=( ${B_PATH}/include/postgresql ${B_PATH}/include/libpq-fe.h ${B_PATH}/include/pg_config_manual.h ${B_PATH}/include/libpq ${B_PATH}/include/postgres_ext.h ) # The linker function cannot accomadate this special purpose. local i for (( i=0; $i < ${#sources[@]}; i++ )) ; do # Remove target before creating the symlink rm -f ${targets[$i]} # Check if link_target still exists [ -e ${targets[$i]} ] && die -q "The target '${targets[$i]}' exists and could not be removed!" ln -s ${sources[$i]} ${targets[$i]} || die -q "Unable to create link!" echo ${targets[$i]} >> ${E_PATH}/active.links done # Link modules to /usr/lib{,lib32,lib64}/ local x for x in ${LIB_LIST} ; do if [ -d ${B_PATH}/${x}/postgresql-${SLOT}/${x} ] ; then # 'linker' function doesn't work for linking directories. # Default lib path ln -s ${B_PATH}/${x}/postgresql-${SLOT}/${x} ${B_PATH}/${x}/postgresql echo ${B_PATH}/${x}/postgresql >> ${E_PATH}/active.links # Linker works for files linker "${B_PATH}/${x}/postgresql-${SLOT}/${x}/lib*.{a,dylib,so}" "${B_PATH}/${x}" fi done # Link binaries to /usr/bin/ linker "${B_PATH}/${LIBDIR}/postgresql-${SLOT}/bin/*" "${B_PATH}/bin" # Default share path ln -s ${B_PATH}/share/postgresql-${SLOT} ${B_PATH}/share/postgresql echo ${B_PATH}/share/postgresql >> ${E_PATH}/active.links echo ${SLOT} > ${E_PATH}/active echo "done." echo -e "\033[1mSetting ${SLOT} as default was successful!\033[0m" } ### Unset Action ### describe_unset() { echo "Remove symbolic links." } do_unset() { local SLOT=$1 if [ "${SLOT}" = "${ACTIVE_SLOT}" ] ; then echo -n "Unsetting ${SLOT} as the default installation..." unlinker ${E_PATH}/active.links rm -f ${E_PATH}/active echo "done." else echo "Inactive slot selected. No work to do." fi } ### Reset Action ### describe_reset() { echo "Recreate symbolic links for currently active slot." } do_reset() { [ "${ACTIVE_SLOT}" = "(none)" ] && die -q "No active slot to reset." do_unset ${ACTIVE_SLOT} do_set ${ACTIVE_SLOT} } ### Update Action ### describe_update() { echo "Refreshes all symbolic links managed by this module" } do_update() { # Check for files managed by postgresql.eselect before 1.0 [ -h /etc/eselect/postgresql/active ] && ACTIVE_SLOT="$(basename $(canonicalise /etc/eselect/postgesql/active))" # Remove service file outright. [ -h /etc/eselect/postgresql/service ] && rm -f /etc/eselect/postgresql/service local slots=($(get_slots)) local index=${#slots[@]} # In case all slots have been unmerged if [ ${index} -eq 0 ] ; then write_warning_msg "No slots found!" write_warning_msg "Removing files (Control-C to abort) in..." local i=6 while [ $[i--] -gt 0 ] ; do echo -n " $i" sleep 1 done for sym_links in ${E_PATH}/active.links* ; do unlinker ${sym_links} done rm -f ${E_PATH}/active rm -f ${ENV_FILE} do_action env update &> /dev/null echo "Done!" return 0 fi # Reset, otherwise set the highest slot available. if [[ ${slots[@]} =~ ${ACTIVE_SLOT} ]] ; then do_reset 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]} fi echo -en "\nCleaning out old links before refreshing..." local sym_links for sym_links in ${E_PATH}/active.links?* ; do unlinker ${sym_links} done echo "done." # Update paths to libs and docs local ldpath local x for x in ${LIB_LIST} ; do [ -h ${B_PATH}/${x}/postgresql ] && ldpath+="${B_PATH}/${x}/postgresql:" done ldpath="${ldpath%:}" local manpath="${B_PATH}/share/postgresql/" while [ $[--index] -gt -1 ] ; do local curslot="${slots[$index]}" echo -n "Refreshing symbolic links for ${curslot} applications (like /usr/bin/psql${curslot//.})..." for x in ${LIB_LIST} ; do local lib_path="${B_PATH}/${x}/postgresql-${curslot}/${x}/" [ -d ${lib_path} ] && ldpath+=":${lib_path}" done local share_path="${B_PATH}/share/postgresql-${curslot}/" [ -d ${share_path} ] && manpath+=":${share_path}" linker "${B_PATH}/${LIBDIR}/postgresql-${curslot}/bin/*" "${B_PATH}/bin" "${curslot//.}" echo "done." done # Remove environment files that have been generated by the ebuilds rm -f ${ENV_FILE}-* store_config ${ENV_FILE} LDPATH "${ldpath}" store_config ${ENV_FILE} MANPATH "${manpath}" do_action env update &> /dev/null }