public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-dev] RFC: postgresql.eselect
@ 2011-03-29  3:19 Aaron W. Swenson
  2011-03-29  9:06 ` Ulrich Mueller
  0 siblings, 1 reply; 7+ messages in thread
From: Aaron W. Swenson @ 2011-03-29  3:19 UTC (permalink / raw
  To: gentoo-dev

[-- Attachment #1: Type: text/plain, Size: 1125 bytes --]

Dear List,

This module is to replace the existing one that is shipped with
<app-admin/eselect-postgresql-1.0.3. It is an entire rewrite.

Changes can be tracked at:
http://git.overlays.gentoo.org/gitweb/?p=proj/pgsql-patches.git;a=shortlog;h=refs/heads/eselect

Before you start reading the attached module, please bear in mind that I
am a novice at writing BASH scripts, and am not intimately familiar with
all the nuances of the language.

There is some duplication of work within the module when compared with
the current postgresql-{base,server}-*.ebuilds in the tree. The plan is
to move that work being handled in the ebuilds to the module.

Setting a service slot has been dropped from the module as it is no
longer necessary.

Features:
* Supports --brief output
* Prefix compatible
* Slot specific application links (e.g., psql90, createdb84)
* Automatically sets the highest slot available as the default unless a
  valid slot is already set
* Properly orders LDPATH giving preference to the set slot and then
  lists the other slots in descending order

Thank you.

Sincerely,
  Mr. Aaron W. Swenson (TitanOfOld)

[-- Attachment #2: postgresql.eselect --]
[-- Type: text/plain, Size: 8589 bytes --]

# 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
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [gentoo-dev] RFC: postgresql.eselect
  2011-03-29  3:19 [gentoo-dev] RFC: postgresql.eselect Aaron W. Swenson
@ 2011-03-29  9:06 ` Ulrich Mueller
  2011-03-29 21:05   ` Aaron W. Swenson
  0 siblings, 1 reply; 7+ messages in thread
From: Ulrich Mueller @ 2011-03-29  9:06 UTC (permalink / raw
  To: gentoo-dev

>>>>> On Mon, 28 Mar 2011, Aaron W Swenson wrote:

> This module is to replace the existing one that is shipped with
> <app-admin/eselect-postgresql-1.0.3. It is an entire rewrite.

Some remarks:

- Global scope code is a no-no in eselect modules, especially if it
  calls external programs or accesses external files. Your module
  will be sourced for commands like "eselect modules list" and there
  shouldn't be any global scope code being run on such occasions.

- Don't use eval. It's almost always an indication that you're doing
  something wrong.

- For tests, please use [[ ]] rather than [ ] throughout.

- "output" and "path-manipulation" libraries are always loaded, so you
  need not (and in fact, you shouldn't) inherit them.

- Don't hardcode terminal specific escape sequences (like "\033[1m").
  Use the highlighting functions of the output library instead (which
  in turn use tput).

- Suppressing stdout of commands like "do_action env update" is fine,
  but why suppress stderr?

- Please avoid lines wider than 79 positions.

See also eselect's README and the developer guide:
<http://sources.gentoo.org/cgi-bin/viewvc.cgi/eselect/trunk/README>
<http://www.gentoo.org/proj/en/eselect/dev-guide.xml>

Ulrich



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [gentoo-dev] RFC: postgresql.eselect
  2011-03-29  9:06 ` Ulrich Mueller
@ 2011-03-29 21:05   ` Aaron W. Swenson
  2011-03-30  4:35     ` [gentoo-dev] " Ryan Hill
  0 siblings, 1 reply; 7+ messages in thread
From: Aaron W. Swenson @ 2011-03-29 21:05 UTC (permalink / raw
  To: gentoo-dev

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On 03/29/2011 05:06 AM, Ulrich Mueller wrote:
>>>>>> On Mon, 28 Mar 2011, Aaron W Swenson wrote:
> 
>> This module is to replace the existing one that is shipped with
>> <app-admin/eselect-postgresql-1.0.3. It is an entire rewrite.
> 
> Some remarks:
> 
> - Global scope code is a no-no in eselect modules, especially if it
>   calls external programs or accesses external files. Your module
>   will be sourced for commands like "eselect modules list" and there
>   shouldn't be any global scope code being run on such occasions.
> 
Fixed.

> - Don't use eval. It's almost always an indication that you're doing
>   something wrong.
> 
Yeah, I should have used 'find' as fewer "tricks" are needed. Wonder why
I didn't do that in the first place....

> - For tests, please use [[ ]] rather than [ ] throughout.
> 
Done.

> - "output" and "path-manipulation" libraries are always loaded, so you
>   need not (and in fact, you shouldn't) inherit them.
> 
The dev guide could be clearer on that. Removed them from the inherit line.

> - Don't hardcode terminal specific escape sequences (like "\033[1m").
>   Use the highlighting functions of the output library instead (which
>   in turn use tput).
> 
Except $(highlight ...) doesn't work in plain echo. So, I just stripped
it out.

> - Suppressing stdout of commands like "do_action env update" is fine,
>   but why suppress stderr?
> 
Because 'ls' would complain that files didn't exist, such as lib*.dylib
when on a Linux system. It doesn't matter. But, using 'find' avoids this
mess.

> - Please avoid lines wider than 79 positions.
> 
Did where I could.

> See also eselect's README and the developer guide:
> <http://sources.gentoo.org/cgi-bin/viewvc.cgi/eselect/trunk/README>
Never knew that existed. Thanks for pointing that out.

> <http://www.gentoo.org/proj/en/eselect/dev-guide.xml>
> 
That's where I got all of my information.

> Ulrich
> 

Thank you for the feedback. It was quite helpful.

Now, I'm a bit sketchy on the handling of choosing which bitness for the
executables. (psql and friends.)

Sincerely,
  Mr. Aaron W. Swenson
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iF4EAREIAAYFAk2SSX0ACgkQCOhwUhu5AEk4xQD9E6jabiGSNYycJSU871p82H1O
0iIU1kBV2HMhfJId/NgA/0Zoq2O3Pcy9O2OcthsQb6e8ZipJZ+dpffMCaC0zOqrs
=L/aO
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [gentoo-dev] Re: RFC: postgresql.eselect
  2011-03-29 21:05   ` Aaron W. Swenson
@ 2011-03-30  4:35     ` Ryan Hill
  2011-03-30  7:58       ` Fabian Groffen
  0 siblings, 1 reply; 7+ messages in thread
From: Ryan Hill @ 2011-03-30  4:35 UTC (permalink / raw
  To: gentoo-dev

[-- Attachment #1: Type: text/plain, Size: 952 bytes --]

On Tue, 29 Mar 2011 17:05:01 -0400
"Aaron W. Swenson" <titanofold@gentoo.org> wrote:

> > - Suppressing stdout of commands like "do_action env update" is fine,
> >   but why suppress stderr?
> > 
> Because 'ls' would complain that files didn't exist, such as lib*.dylib
> when on a Linux system. It doesn't matter. But, using 'find' avoids this
> mess.

Never use ls to get filenames in a script.  Instead of 

  for link_source in $(eval ls ${source_dir} 2> /dev/null) ; do

just use

  for link_source in "${source_dir}"/* ; do

I see you already fixed this one, but you do some funky stuff with ls -d
earlier on.

http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29


-- 
fonts, gcc-porting,                  it makes no sense how it makes no sense
toolchain, wxwidgets                           but i'll take it free anytime
@ gentoo.org                EFFD 380E 047A 4B51 D2BD C64F 8AA8 8346 F9A4 0662

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [gentoo-dev] Re: RFC: postgresql.eselect
  2011-03-30  4:35     ` [gentoo-dev] " Ryan Hill
@ 2011-03-30  7:58       ` Fabian Groffen
  2011-03-30 11:00         ` Aaron W. Swenson
  0 siblings, 1 reply; 7+ messages in thread
From: Fabian Groffen @ 2011-03-30  7:58 UTC (permalink / raw
  To: gentoo-dev

On 29-03-2011 22:35:48 -0600, Ryan Hill wrote:
> > Because 'ls' would complain that files didn't exist, such as lib*.dylib
> > when on a Linux system. It doesn't matter. But, using 'find' avoids this
> > mess.
> 
> Never use ls to get filenames in a script.  Instead of 
> 
>   for link_source in $(eval ls ${source_dir} 2> /dev/null) ; do
> 
> just use
> 
>   for link_source in "${source_dir}"/* ; do
> 
> I see you already fixed this one, but you do some funky stuff with ls -d
> earlier on.

Make sure though, when you use a glob, that you check for the asterisk.

When there are no matches, bash assumes you meant the literal '*' and
hence will return "/foo/bar/*" in link_source.
So make sure you check the existence of whatever is in link_source
before using it.


-- 
Fabian Groffen
Gentoo on a different level



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [gentoo-dev] Re: RFC: postgresql.eselect
  2011-03-30  7:58       ` Fabian Groffen
@ 2011-03-30 11:00         ` Aaron W. Swenson
  2011-03-30 22:53           ` Ryan Hill
  0 siblings, 1 reply; 7+ messages in thread
From: Aaron W. Swenson @ 2011-03-30 11:00 UTC (permalink / raw
  To: gentoo-dev

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On 03/30/2011 03:58 AM, Fabian Groffen wrote:
> On 29-03-2011 22:35:48 -0600, Ryan Hill wrote:
>>> Because 'ls' would complain that files didn't exist, such as lib*.dylib
>>> when on a Linux system. It doesn't matter. But, using 'find' avoids this
>>> mess.
>>
>> Never use ls to get filenames in a script.  Instead of 
>>
>>   for link_source in $(eval ls ${source_dir} 2> /dev/null) ; do
>>
>> just use
>>
>>   for link_source in "${source_dir}"/* ; do
>>
>> I see you already fixed this one, but you do some funky stuff with ls -d
>> earlier on.
> 
> Make sure though, when you use a glob, that you check for the asterisk.
> 
> When there are no matches, bash assumes you meant the literal '*' and
> hence will return "/foo/bar/*" in link_source.
> So make sure you check the existence of whatever is in link_source
> before using it.
> 
> 
Yup, that's part of the reason why I changed to 'find' rather than 'ls'
there. 'find' will return a list matching the criteria, or it'll be
empty. Again, why I didn't use it earlier is beyond me. I think 'ls'
just worked for me and I moved on to getting other bits to work and
forgot about it.

As for the lib_dir(), I'm unsure if that's a good way to handle things.
Or, if it's really the best way, even though it's ugly. There's nothing
preventing me from making it a user configurable...it's just that at
some point I do need to determine the default bitness for the applications.

- - Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iF4EAREIAAYFAk2TDUQACgkQCOhwUhu5AEnnnAD/QPHQ2B3VUlFBQpCBg/8zdXDE
StAmxwYONYECac7ZZdYBAK0YW+JZYo4wez/U+OMNz6bMobNJrlC/e8TPgBQrHYd1
=ppf+
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [gentoo-dev] Re: RFC: postgresql.eselect
  2011-03-30 11:00         ` Aaron W. Swenson
@ 2011-03-30 22:53           ` Ryan Hill
  0 siblings, 0 replies; 7+ messages in thread
From: Ryan Hill @ 2011-03-30 22:53 UTC (permalink / raw
  To: gentoo-dev

[-- Attachment #1: Type: text/plain, Size: 798 bytes --]

On Wed, 30 Mar 2011 07:00:21 -0400
"Aaron W. Swenson" <titanofold@gentoo.org> wrote:

> As for the lib_dir(), I'm unsure if that's a good way to handle things.
> Or, if it's really the best way, even though it's ugly. There's nothing
> preventing me from making it a user configurable...it's just that at
> some point I do need to determine the default bitness for the applications.

Actually I was thinking about it and the libdir stuff isn't that bad since
you're just comparing to "", ie. not bad in that it should always work as
intended.


-- 
fonts, gcc-porting,                  it makes no sense how it makes no sense
toolchain, wxwidgets                           but i'll take it free anytime
@ gentoo.org                EFFD 380E 047A 4B51 D2BD C64F 8AA8 8346 F9A4 0662

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-03-30 22:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-29  3:19 [gentoo-dev] RFC: postgresql.eselect Aaron W. Swenson
2011-03-29  9:06 ` Ulrich Mueller
2011-03-29 21:05   ` Aaron W. Swenson
2011-03-30  4:35     ` [gentoo-dev] " Ryan Hill
2011-03-30  7:58       ` Fabian Groffen
2011-03-30 11:00         ` Aaron W. Swenson
2011-03-30 22:53           ` Ryan Hill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox