public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Patrick McLean" <chutzpah@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/eselect:extern commit in: modules/
Date: Sat,  9 May 2020 02:22:29 +0000 (UTC)	[thread overview]
Message-ID: <1588990941.4fd0650ed9ef4cec5477038fcfb2e59db2cf2b93.chutzpah@gentoo> (raw)

commit:     4fd0650ed9ef4cec5477038fcfb2e59db2cf2b93
Author:     Patrick McLean <patrick.mclean <AT> sony <DOT> com>
AuthorDate: Sat May  9 02:21:40 2020 +0000
Commit:     Patrick McLean <chutzpah <AT> gentoo <DOT> org>
CommitDate: Sat May  9 02:22:21 2020 +0000
URL:        https://gitweb.gentoo.org/proj/eselect.git/commit/?id=4fd0650e

modules/iptables.eselect: Complete rewrite, solve issues in bug #721578

Signed-off-by: Patrick McLean <patrick.mclean <AT> sony.com>

 modules/iptables.eselect | 320 +++++++++++++++++++++++++++++++----------------
 1 file changed, 214 insertions(+), 106 deletions(-)

diff --git a/modules/iptables.eselect b/modules/iptables.eselect
index f94b25c..e3e5906 100644
--- a/modules/iptables.eselect
+++ b/modules/iptables.eselect
@@ -2,43 +2,128 @@
 # Copyright 2005-2020 Gentoo Authors
 # Distributed under the terms of the GNU GPL version 2 or later
 
-DESCRIPTION="Manage the iptables and ip6tables symlink"
-AUTHOR="chris@christopherpritchard.co.uk"
+inherit package-manager
+
+DESCRIPTION="Manage the iptables/arptables/ebtables symlinks"
 MAINTAINER="base-system@gentoo.org"
-VERSION="20200319"
+VERSION="20200508"
+
+# a simple list of symlinks does for iptables
+IPTABLES_SYMLINKS=(
+	"iptables-xml"
+	"iptables" "iptables-restore" "iptables-save"
+)
+IP6TABLES_SYMLINKS=(
+	"ip6tables" "ip6tables-restore" "ip6tables-save"
+)
+
+# for arptables and ebtables we map names to legacy targets
+ARPTABLES_TARGETS=(
+	"arptables-legacy"
+	"xtables-nft-multi"
+)
+declare -A ARPTABLES_SYMLINKS=(
+	[arptables]="arptables-legacy"
+	[arptables-restore]="arptables-legacy-restore"
+	[arptables-save]="arptables-legacy-save"
+)
+
+EBTABLES_TARGETS=(
+	"ebtables-legacy"
+	"xtables-nft-multi"
+)
+declare -A EBTABLES_SYMLINKS=(
+	[ebtables]="ebtables-legacy"
+	[ebtables-restore]="ebtables-legacy-restore"
+	[ebtables-save]="ebtables-legacy-save"
+)
 
-IPTABLES_TARGETS=("iptables" "iptables-restore" "iptables-save")
-IP6TABLES_TARGETS=("ip6tables" "ip6tables-restore" "ip6tables-save")
+# get which module is running
+get_module() {
+	local module
+	module="${BASH_SOURCE[0]##*/}"
 
-# find a list of xtables symlink targets
+	printf -- '%s\n' "${module%.eselect}"
+}
+
+# find a list of symlink targets for the current module
 find_targets() {
-	local f
-	for f in "${EROOT}"/sbin/xtables-*-multi; do
-		[[ -f ${f} ]] && basename "${f}"
-	done
+	local module target
+
+	module="$(get_module)"
+	case "${module}" in
+		iptables)
+			for target in "${EROOT}"/sbin/xtables-*-multi; do
+				[[ -x ${target} ]] && printf -- '%s\n' "${target##*/}"
+			done
+		;;
+		arptables)
+			for target in "${ARPTABLES_TARGETS[@]}"; do
+				[[ -x ${EROOT}/sbin/${target} ]] && printf -- '%s\n' "${target}"
+			done
+		;;
+		ebtables)
+			for target in "${EBTABLES_TARGETS[@]}"; do
+				[[ -x ${EROOT}/sbin/${target} ]] && printf -- '%s\n' "${target}"
+			done
+		;;
+		*) die "Invalid module name ${module}"
+	esac
 }
 
-# remove the iptables symlink
-remove_symlinks() {
-	local ipt
-	for ipt in "${IPTABLES_TARGETS[@]}"; do
-		rm -f "${EROOT}/sbin/${ipt}" &>/dev/null
-	done
-	if [[ -n ${ipv6} && -n ${ipv6_remove} ]]; then
-		local ip6t
-		for ip6t in "${IP6TABLES_TARGETS[@]}"; do
-			rm -f "${EROOT}/sbin/${ip6t}" &>/dev/null
-		done
-	fi
+# get the list of symlinks for the current module
+get_symlinks_list() {
+	local module
+	module="$(get_module)"
+
+	case "${module}" in
+		iptables)
+			printf -- '%s\n' "${IPTABLES_SYMLINKS[@]}"
+
+			if [[ ${1} == -a ]] || has_version 'net-firewall/iptables[ipv6]'
+			then
+				printf -- '%s\n' "${IP6TABLES_SYMLINKS[@]}"
+			fi
+		;;
+		arptables) printf -- '%s\n' "${!ARPTABLES_SYMLINKS[@]}";;
+		ebtables) printf -- '%s\n' "${!EBTABLES_SYMLINKS[@]}";;
+		*) die "Invalid module name ${module}"
+	esac
+}
+
+# get the symlink target given a symlink name and the target implementation
+get_symlink_target() {	
+	local link="${1}" target="${2}" module
+	module="$(get_module)"
+
+	case "${module}" in
+		iptables) printf -- '%s\n' "${target}";;
+		arptables)
+			if [[ ${target} == *-legacy ]]; then
+				printf -- '%s\n' "${ARPTABLES_SYMLINKS[${link}]}"
+			else
+				printf -- '%s\n' "${target}"
+			fi
+		;;
+		ebtables)
+			if [[ ${target} == *-legacy ]]; then
+				printf -- '%s\n' "${EBTABLES_SYMLINKS[${link}]}"
+			else
+				printf -- '%s\n' "${target}"
+			fi
+		;;
+		*) die "Invalid module name ${module}"
+	esac
 }
 
-# set the iptables symlink
+# set the symlinks for the current target
 set_symlinks() {
 	local target="${1}"
+	local retval=0
 
 	if is_number "${target}" && [[ ${target} -ge 1 ]]; then
 		local -a targets
-		readarray -t targets <<< "$(find_targets)"
+		readarray -t targets < <(find_targets)
 		target=${targets[$((target-1))]}
 	fi
 
@@ -46,130 +131,153 @@ set_symlinks() {
 		die -q "Target \"${target}\" doesn't appear to be valid!"
 	fi
 
-	local ipt
-	for ipt in "${IPTABLES_TARGETS[@]}"; do
-	  ln -s "${target}" "${EROOT}/sbin/${ipt}"
-	done
+	# create an array of symlinks to be created, then create them
+	# in a separate pass, it's done this way in an attempt to be atomic
+	# either all symlinks get updated, or none
+	local -a symlinks_list
+	readarray -t symlinks_list < <(get_symlinks_list)
+
+	local symlink
+	local -A do_symlinks
+	for symlink in "${symlinks_list[@]}"; do
+		local symlink_path="${EROOT}/sbin/${symlink}"
+
+		if [[ -L ${symlink_path} || ! -e ${symlink_path} ]]; then
+			do_symlinks["${symlink_path}"]="$(get_symlink_target "${symlink}" "${target}")"
 	
-	if [[ -n ${ipv6} ]]; then
-		local ip6t
-		for ip6t in "${IP6TABLES_TARGETS[@]}"; do
-			ln -s "${target}" "${EROOT}/sbin/${ip6t}"
-		done
-	fi
+		else
+			die -q "Could not create symlink at ${symlink_path}:" \
+				"path exits and is not a symlink"
+		fi
+	done
+
+	for symlink in "${!do_symlinks[@]}"; do
+		if ! ln -sfn "${do_symlinks["${symlink}"]}" "${symlink}"; then
+			write_error_message "Failed to create symlink at ${symlink}"
+			retval=1
+		fi
+	done
+
+	return "${retval}"
 }
 
 ### show action ###
 
 describe_show() {
-	echo "Show the current iptables symlink"
+	printf -- 'Show the current %s symlink\n' "$(get_module)"
 }
 
 do_show() {
-	local ipv6
-	if [[ -d ${EROOT}/var/lib/ip6tables ]]; then
-		ipv6=1
-	fi
-	write_list_start "Current iptables symlinks:"
-	local ipt all_unset=1
-	for ipt in "${IPTABLES_TARGETS[@]}"; do
-		if [[ -L ${EROOT}/sbin/${ipt} ]]; then
-			local ipta
-			ipta=$(canonicalise "${EROOT}/sbin/${ipt}")
-			write_kv_list_entry "${ipt}" "${ipta%/}"
+	local -a symlinks_list
+	readarray -t symlinks_list < <(get_symlinks_list)
+
+	local all_unset=1 symlink
+	write_list_start "Current $(get_module) symlinks:"
+	for symlink in "${symlinks_list[@]}"; do
+		symlink_path="${EROOT}/sbin/${symlink}"
+
+		if [[ -L ${symlink_path} ]]; then
+			local symlink_target
+			symlink_target=$(canonicalise "${symlink_path}")
+			write_kv_list_entry "${symlink}" "${symlink_target%/}"
 			all_unset=0
-		else
-			write_kv_list_entry "${ipt}" "(unset)"
+		elif [[ ! -f ${symlink_path} ]]; then
+			write_kv_list_entry "${symlink}" "(unset)"
 	  fi
 	done
-	if [[ ${ipv6} -eq 1 ]]; then
-		write_list_start "Current ip6tables symlinks:"
-		local ip6t
-		for ip6t in "${IP6TABLES_TARGETS[@]}"; do
-			if [[ -L ${EROOT}/sbin/${ip6t} ]]; then
-				local ipta
-				ipta=$(canonicalise "${EROOT}/sbin/${ip6t}")
-				write_kv_list_entry "${ip6t}" "${ipta%/}"
-				all_unset=0
-			else
-				write_kv_list_entry "${ip6t}" "(unset)"
-			fi
-		done
-	fi
+
 	return "${all_unset}"
 }
 ### list action ###
 
 describe_list() {
-	echo "List available iptables symlink targets"
+	printf -- 'List available %s symlink targets\n' "$(get_module)"
 }
 
 do_list() {
-	local ipv6
-	local -a targets
-	readarray -t targets <<< "$(find_targets)"
-	if [[ -L ${EROOT}/var/lib/ip6tables ]]; then
-		ipv6=1
-	fi
-	write_list_start "Available iptables symlink targets:"
-	local i
-	for (( i = 0; i < ${#targets[@]}; i++ )); do
-		# highlight the target where the symlink is pointing to
-		[[ ${targets[i]} = \
-			$(basename "$(canonicalise "${EROOT}/sbin/iptables")") ]] \
-			&& targets[i]=$(highlight_marker "${targets[i]}")
+	local module
+	module="$(get_module)"
+
+	local -a targets_list symlinks_list
+	readarray -t targets_list < <(find_targets)
+	readarray -t symlinks_list < <(get_symlinks_list)
+
+	local -a targets_output
+
+	write_list_start "Available ${module} symlink targets:"
+	local symlink current_target
+	for symlink in "${symlinks_list[@]}"; do
+		local symlink_path="${EROOT}/sbin/${symlink}"
+		local target
+		for target in "${targets_list[@]}"; do
+			local symlink_target resolved_target
+			symlink_target="$(get_symlink_target "${symlink}" "${target}")"
+			resolved_target="$(basename "$(canonicalise "${symlink_path}")")"
+
+			if [[ ${resolved_target} == "${symlink_target}" ]]; then
+				if [[ -z ${current_target} ]]; then
+					current_target="${target}"
+					break
+				elif [[ ${current_target} != "${target}" ]]; then
+					write_warning_msg "Target mismatch"
+					unset current_target
+					break 2
+				fi
+			fi
+		done
+	done
+	for target in "${targets_list[@]}"; do
+		if [[ ${target} == "${current_target}" ]]; then
+			targets_output+=("$(highlight_marker "${target}")")
+		else
+			targets_output+=("${target}")
+		fi
 	done
-	write_numbered_list -m "(none found)" "${targets[@]}"
+
+	write_numbered_list -m "(none found)" "${targets_output[@]}"
 }
 
 ### set action ###
 
 describe_set() {
-	echo "Set a new iptables symlink target"
-}
-
-describe_set_parameters() {
-	echo "[--ipv6] <target>"
+	printf "Set a new $(get_module) symlink target\\n"
 }
 
 describe_set_options() {
-	echo "--ipv6: Forces creation of ip6tables symlinks"
-	echo "target : Target name or number (from 'list' action)"
+	printf -- "target : Target name or number (from 'list' action)\\n"
 }
 
 do_set() {
-	local ipv6 ipv6_remove
-	if [[ ${1} == "--ipv6" ]]; then
-		ipv6=1
-		shift
-	fi
 	local target="${1}"
 
 	[[ -z ${target} ]] && die -q "You didn't tell me what to set the symlink to"
-	[[ ${#} -gt 2 ]] && die -q "Too many parameters"
+	[[ ${#} -gt 1 ]] && die -q "Too many parameters"
 
-	if [[ -d ${EROOT}/var/lib/ip6tables ]]; then
-		ipv6=1
-		[[ -L ${EROOT}/sbin/ip6tables ]] && ipv6_remove=1
-	fi
-	if [[ -L ${EROOT}/sbin/iptables ]]; then
-		# existing symlink
-		remove_symlinks || die -q "Couldn't remove existing symlink"
-		set_symlinks "${target}" || die -q "Couldn't set a new symlink"
-	elif [[ -e ${EROOT}/sbin/iptables ]]; then
-		# we have something strange
-		die -q "${EROOT}/sbin/iptables exists but is not a symlink"
-	else
-		set_symlinks "${target}" || die -q "Couldn't set a new symlink"
-	fi
+	set_symlinks "${target}" || die -q "Couldn't set symlinks"
 }
 
 ### unset action ###
 
 describe_unset() {
-	echo "Unset iptables symlink targets"
+	printf -- 'Unset %s symlink targets\n' "$(get_module)"
 }
 
 do_unset() {
-	remove_symlinks
+	local retval=0
+
+	local -a symlinks_list
+	readarray -t symlinks_list < <(get_symlinks_list -a)
+
+	local symlink
+	for symlink in "${symlinks_list[@]}"; do
+		local symlink_path="${EROOT}/sbin/${symlink}"
+		if [[ -L ${symlink_path} ]]; then
+			unlink "${symlink_path}" || retval=${?}
+		elif [[ -e ${symlink_path} ]]; then
+			write_error_msg "Not removing non-symlink \"${symlink_path}\""
+			retval=1
+		fi
+	done
+
+	return ${retval}
 }


             reply	other threads:[~2020-05-09  2:22 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-09  2:22 Patrick McLean [this message]
  -- strict thread matches above, loose matches on Subject: below --
2018-08-30 16:48 [gentoo-commits] proj/eselect:extern commit in: modules/ Ulrich Müller
2018-03-10 10:22 Ulrich Müller
2018-03-10 10:22 Ulrich Müller
2018-03-10 10:22 Ulrich Müller
2015-02-26  6:52 Ben de Groot
2015-01-04 10:00 Michał Górny
2015-01-04 10:00 Michał Górny
2015-01-04 10:00 Michał Górny
2013-12-30  7:49 Ryan Hill
2013-11-17  8:34 Ryan Hill
2013-09-20 20:34 Ulrich Mueller
2013-03-11  7:06 Ulrich Mueller
2013-03-11  2:16 Christoph Junghans
2013-03-11  2:16 Christoph Junghans
2013-03-11  2:16 Christoph Junghans
2013-01-05 15:35 Ulrich Mueller
2012-06-21 12:26 Luca Barbato

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1588990941.4fd0650ed9ef4cec5477038fcfb2e59db2cf2b93.chutzpah@gentoo \
    --to=chutzpah@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox