# Copyright 1999-2005 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: mysql.eselect,v 1.12 2006/02/15 02:34:44 vivo Exp $ DESCRIPTION="Manage the /usr/lib/*mysql* links" MAINTAINER="vivo@gentoo.org" SVN_DATE='$Date: 2006/02/15 02:34:44 $' VERSION=$(svn_date_to_version "${SVN_DATE}" ) MYSQL_SYMLINK_CHECKDIR="${ROOT}/usr/bin" ERR_NOT_FOUND="(not-found)" # "unset" is grepped by the MySQL ebuild so don't touch it ERR_UNSET="(unset)" # return a human oriented version # # $1 - version to transform function version4human() { local major=${1:0:1} local minor=${1:1:2} [[ ${minor:0:1} == "0" ]] && minor=${minor:1:1} echo "${major}.${minor}.x" } # return a integer version # # $1 - version to transform function version4bash() { local minor=${1#*.} minor=${minor%%.x*} [[ ${#minor} -lt 10 ]] && minor="0${minor}" echo "${1%%.*}${minor}" } # Return the versions currently installed find_versions() { local versions list # "eselect mysql set 1" will always set the best version list=$( ls ${MYSQL_SYMLINK_CHECKDIR}/perror-* 2>/dev/null ) for x in ${list} ; do versions=( $( version4human ${x##*-}) ${versions[@]} ) done echo ${versions[@]} } # Check if a symlink could be created for a specific file # # $1 - original file name # $2 - MySQL version check_symlink() { local filename=${1} local version=${2} local linkname=${filename/"-${version}"/} local ret=0 [[ -z ${filename} ]] || [[ -z ${version} ]] && return 1 # check link source [[ -f "${filename}" ]] || [[ -f "${filename}.gz" ]] || [[ -d ${filename} ]] || ret=$(( ${ret} + 1 )) # check link targe # not checking for directory (want to keep "/etc/mysql") [[ -a ${linkname} ]] && [[ ! -L ${linkname} ]] && [[ ! -d ${linkname} ]] \ && ret=$(( ${ret} +2 )) return ${ret} } # another one inherited from versionator.eclass (version_sort) # THERE IS A COPY OF THIS ONE IN MYSQL_FX.ECLASS, keep the two synced mysql_make_file_list() { local items= left=0 items=$( ls -d ${1}-[[:digit:]][[:digit:]][[:digit:]] ) while [[ ${left} -lt ${#items[@]} ]] ; do local lowest_idx=${left} local idx=$(( ${lowest_idx} + 1 )) while [[ ${idx} -lt ${#items[@]} ]] ; do [[ "${items[${lowest_idx}]}" > "${items[${idx}]}" ]] \ && lowest_idx=${idx} idx=$(( ${idx} + 1 )) done local tmp=${items[${lowest_idx}]} items[${lowest_idx}]=${items[${left}]} items[${left}]=${tmp} left=$(( ${left} + 1 )) done echo ${items[@]} } # THERE IS A COPY OF THIS ONE IN ESELECT-MYSQL, keep the two synced mysql_choose_better_version() { local items= better="" i items="$( ls -d ${1}-[[:digit:]][[:digit:]][[:digit:]] )" for i in ${items} ; do if [[ "${i}" > "${better}" ]] ; then better="${i}" fi done echo "${better}" } # void mysql_lib_symlinks() # # To be called on the live filesystem, reassign symlinks to each mysql # library to the best version avaiable # 2005-12-30 # THERE IS A COPY OF THIS ONE IN MYSQL_FX.ECLASS, keep the two synced mysql_lib_symlinks() { local d dirlist maxdots soname sonameln other better pushd "${ROOT}/usr/lib" &> /dev/null # dirlist must contain the less significative directory left dirlist="mysql $( mysql_make_file_list mysql )" # waste some time in removing and recreating symlinks for d in $dirlist ; do for soname in $( find "${d}" -name "*.so*" -and -not -type "l" 2>/dev/null) do # maxdot is a limit versus infinite loop maxdots=0 sonameln=${soname##*/} # loop in version of the library to link it, similar to the # libtool work while [[ ${sonameln:0-3} != '.so' ]] && [[ ${maxdots} -lt 6 ]] do rm -f "${sonameln}" ln -s "${soname}" "${sonameln}" (( ++maxdots )) sonameln="${sonameln%.*}" done rm -f "${sonameln}" ln -s "${soname}" "${sonameln}" done done popd &> /dev/null # "include"s and "mysql_config", needed to compile other sw for other in "/usr/lib/mysql" "/usr/include/mysql" "/usr/bin/mysql_config" ; do pushd "${ROOT}${other%/*}" &> /dev/null better=$( mysql_choose_better_version "${other##*/}" ) if ! [[ -d "${other##*/}" ]] ; then [[ -L "${other##*/}" ]] && rm -f "${other##*/}" ! [[ -f "${other##*/}" ]] && ln -sf "${better}" "${other##*/}" else [[ -L "${other##*/}" ]] && rm -f "${other##*/}" ! [[ -d "${other##*/}" ]] && ln -s "${better}" "${other##*/}" fi popd &> /dev/null done } # work out which MYSQL version the user has chosen from the list # # $1: the list id that the user has chosen get_version_fromlist() { local version=${1} local -a versions=( $(find_versions) ) if is_number ${version} ; then if [[ ${version} -gt 0 ]] && [[ ${version} -le ${#versions[@]} ]] ; then version=${versions[(( ${version} - 1 ))]} echo "${version}" return fi fi for (( i = 0 ; i < ${#versions[@]} ; i = i + 1 )) ; do [[ ${versions[$i]} == ${version} ]] || continue echo ${version} return done echo "${ERR_NOT_FOUND}" } get_current_version() { link=$(readlink ${MYSQL_SYMLINK_CHECKDIR}/perror) version=${link##*-} if ! is_number "${version}" || [[ "${version}" == "" ]] ; then version="${ERR_UNSET}" echo "${version}" else echo $(version4human "${version}") fi } set_current_version() { local version=${1} is_number "${version}" || die -q "No usable version: ${version}" local CWD=$(pwd) local lastdir dir linkname local list=$(< $ROOT/var/lib/eselect/mysql/mysql-${version}.filelist ) # perform a check on the entire file lis for filename in $list ; do dir="${ROOT}/$(dirname "${filename}")" if [[ "${dir}" != "${lastdir}" ]] ; then cd "${dir}" lastdir="${dir}" fi check_symlink "$(basename "${filename}")" "${version}" ret=$? if [[ $ret -ne 0 ]] ; then cd "${CWD}" die -q \ "File \"${ROOT}/${filename}\" is not suitable for symlink (${ret})" fi done # it's ok to do the effective work now for filename in $list ; do dir="${ROOT}/$(dirname "${filename}")" if [[ "${dir}" != "${lastdir}" ]] ; then cd "${dir}" lastdir="${dir}" fi linkname="$(basename "${filename}")" if ! [[ -f "${linkname}" ]] && ! [[ -d "${linkname}" ]] \ && [[ -f "${linkname}.gz" ]] then linkname="${linkname}.gz" fi if [[ -a "${linkname}" ]] ; then # rm needed for directory rm -f "${linkname/"-${version}"/}" &> /dev/null ln -sf "${linkname}" "${linkname/"-${version}"/}" [[ ! -L "${linkname/"-${version}"/}" ]] \ && write_warning_msg "FAILED: cd \"${dir}\" && ln -sf \"${linkname}\" \"${linkname/"-${version}"/}\"" fi done cd "${CWD}" } remove_current_version() { local version=${1} is_number "${version}" || die -q "No usable version: ${version}" local CWD=$(pwd) local lastdir dir linkname local list=$(< $ROOT/var/lib/eselect/mysql/mysql-${version}.filelist ) for filename in $list ; do linkname="${ROOT}/${filename/"-${version}"/}" [[ -L "${linkname}" ]] && rm -f "${linkname}" linkname="${ROOT}/${filename/"-${version}"/}.gz" [[ -L "${linkname}" ]] && rm -f "${linkname}" done cd "${CWD}" } ### show action ### describe_show() { echo "Show the current default version for MySQL" } do_show() { write_list_start "Current default MySQL version:" version=$(get_current_version) write_kv_list_entry "$version" "" } ### list action ### describe_list() { echo "List available MySQL versions to link to" } do_list() { versions=( $(find_versions) ) current=$(get_current_version) write_list_start "Available MySQL versions:" if [[ -n "${versions[@]}" ]] ; then local i for (( i = 0 ; i < ${#versions[@]} ; i = i + 1 )) ; do [[ ${versions[${i}]} == ${current} ]] && \ versions[${i}]="${versions[${i}]} $(highlight '*' )" done write_numbered_list "${versions[@]}" else write_kv_list_entry "(none found)" "" fi } ### set action ### describe_set() { echo "Set MYSQL version used" } do_set() { [[ ${#@} -lt 1 ]] && die -q "Wrong count of paramters." local version version=$(get_version_fromlist ${1}) if [[ ${version} == "${ERR_NOT_FOUND}" ]] ; then die -q "I don't recognise that version of MYSQL" fi set_current_version "$(version4bash "${version}")" mysql_lib_symlinks } ### remove action ### describe_remove() { echo "Remove symlinks of the default server" } do_remove() { local version=$(readlink "${MYSQL_SYMLINK_CHECKDIR}/perror") version=$(version4human "${version##*-}") if [[ -z "${version}" ]] ; then die -q "No symlinks found" fi remove_current_version "$(version4bash "${version}")" mysql_lib_symlinks } ### slot_remove action ### describe_slot_remove() { echo "Remove symlinks given a MySQL slot (used in the ebuild)" } do_slot_remove() { [[ ${#@} -lt 1 ]] && die -q "Wrong count of paramters." local version=$( version4human ${1} ) version=$( get_version_fromlist ${version} ) local cur_version=$( get_current_version ) if [[ ${version} == "${ERR_NOT_FOUND}" ]] ; then die -q "I don't recognise that version of MYSQL" fi if [[ -z "${version}" ]] ; then die -q "No symlinks found" fi if [[ "${version}" != "${cur_version}" ]] ; then die -q "The version specified is not the current one" fi remove_current_version "$( version4bash "${version}" )" mysql_lib_symlinks } describe_distclean() { echo "Remove ANY non slotted mysql and slotted symlinks, DANGEROUS" } do_distclean() { local bckfile="${HOME}/eselect-mysql-distclean-backup.tar.bz2" local list=$( cat $ROOT/var/lib/eselect/mysql/mysql-*.filelist \ | sed -e 's/-[0123456789][0123456789][0123456789]//' \ | sort | uniq ) touch "${bckfile}" || die -q "cannot create \"${bckfile}\"" rm -f "${bckfile}" pushd ${ROOT}/ &> /dev/null tar -jcpf "${bckfile}" ${list} 2> /dev/null for f in ${list} ; do [[ "${f:0:3}" == "usr" ]] && rm -rf "${f}" done popd &> /dev/null echo "backup created in \"${bckfile}\"" } # vim: set ft=eselect :