Gentoo Archives: gentoo-commits

From: Patrick McLean <chutzpah@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/eselect:extern commit in: modules/
Date: Sat, 09 May 2020 02:22:34
Message-Id: 1588990941.4fd0650ed9ef4cec5477038fcfb2e59db2cf2b93.chutzpah@gentoo
1 commit: 4fd0650ed9ef4cec5477038fcfb2e59db2cf2b93
2 Author: Patrick McLean <patrick.mclean <AT> sony <DOT> com>
3 AuthorDate: Sat May 9 02:21:40 2020 +0000
4 Commit: Patrick McLean <chutzpah <AT> gentoo <DOT> org>
5 CommitDate: Sat May 9 02:22:21 2020 +0000
6 URL: https://gitweb.gentoo.org/proj/eselect.git/commit/?id=4fd0650e
7
8 modules/iptables.eselect: Complete rewrite, solve issues in bug #721578
9
10 Signed-off-by: Patrick McLean <patrick.mclean <AT> sony.com>
11
12 modules/iptables.eselect | 320 +++++++++++++++++++++++++++++++----------------
13 1 file changed, 214 insertions(+), 106 deletions(-)
14
15 diff --git a/modules/iptables.eselect b/modules/iptables.eselect
16 index f94b25c..e3e5906 100644
17 --- a/modules/iptables.eselect
18 +++ b/modules/iptables.eselect
19 @@ -2,43 +2,128 @@
20 # Copyright 2005-2020 Gentoo Authors
21 # Distributed under the terms of the GNU GPL version 2 or later
22
23 -DESCRIPTION="Manage the iptables and ip6tables symlink"
24 -AUTHOR="chris@×××××××××××××××××××××××.uk"
25 +inherit package-manager
26 +
27 +DESCRIPTION="Manage the iptables/arptables/ebtables symlinks"
28 MAINTAINER="base-system@g.o"
29 -VERSION="20200319"
30 +VERSION="20200508"
31 +
32 +# a simple list of symlinks does for iptables
33 +IPTABLES_SYMLINKS=(
34 + "iptables-xml"
35 + "iptables" "iptables-restore" "iptables-save"
36 +)
37 +IP6TABLES_SYMLINKS=(
38 + "ip6tables" "ip6tables-restore" "ip6tables-save"
39 +)
40 +
41 +# for arptables and ebtables we map names to legacy targets
42 +ARPTABLES_TARGETS=(
43 + "arptables-legacy"
44 + "xtables-nft-multi"
45 +)
46 +declare -A ARPTABLES_SYMLINKS=(
47 + [arptables]="arptables-legacy"
48 + [arptables-restore]="arptables-legacy-restore"
49 + [arptables-save]="arptables-legacy-save"
50 +)
51 +
52 +EBTABLES_TARGETS=(
53 + "ebtables-legacy"
54 + "xtables-nft-multi"
55 +)
56 +declare -A EBTABLES_SYMLINKS=(
57 + [ebtables]="ebtables-legacy"
58 + [ebtables-restore]="ebtables-legacy-restore"
59 + [ebtables-save]="ebtables-legacy-save"
60 +)
61
62 -IPTABLES_TARGETS=("iptables" "iptables-restore" "iptables-save")
63 -IP6TABLES_TARGETS=("ip6tables" "ip6tables-restore" "ip6tables-save")
64 +# get which module is running
65 +get_module() {
66 + local module
67 + module="${BASH_SOURCE[0]##*/}"
68
69 -# find a list of xtables symlink targets
70 + printf -- '%s\n' "${module%.eselect}"
71 +}
72 +
73 +# find a list of symlink targets for the current module
74 find_targets() {
75 - local f
76 - for f in "${EROOT}"/sbin/xtables-*-multi; do
77 - [[ -f ${f} ]] && basename "${f}"
78 - done
79 + local module target
80 +
81 + module="$(get_module)"
82 + case "${module}" in
83 + iptables)
84 + for target in "${EROOT}"/sbin/xtables-*-multi; do
85 + [[ -x ${target} ]] && printf -- '%s\n' "${target##*/}"
86 + done
87 + ;;
88 + arptables)
89 + for target in "${ARPTABLES_TARGETS[@]}"; do
90 + [[ -x ${EROOT}/sbin/${target} ]] && printf -- '%s\n' "${target}"
91 + done
92 + ;;
93 + ebtables)
94 + for target in "${EBTABLES_TARGETS[@]}"; do
95 + [[ -x ${EROOT}/sbin/${target} ]] && printf -- '%s\n' "${target}"
96 + done
97 + ;;
98 + *) die "Invalid module name ${module}"
99 + esac
100 }
101
102 -# remove the iptables symlink
103 -remove_symlinks() {
104 - local ipt
105 - for ipt in "${IPTABLES_TARGETS[@]}"; do
106 - rm -f "${EROOT}/sbin/${ipt}" &>/dev/null
107 - done
108 - if [[ -n ${ipv6} && -n ${ipv6_remove} ]]; then
109 - local ip6t
110 - for ip6t in "${IP6TABLES_TARGETS[@]}"; do
111 - rm -f "${EROOT}/sbin/${ip6t}" &>/dev/null
112 - done
113 - fi
114 +# get the list of symlinks for the current module
115 +get_symlinks_list() {
116 + local module
117 + module="$(get_module)"
118 +
119 + case "${module}" in
120 + iptables)
121 + printf -- '%s\n' "${IPTABLES_SYMLINKS[@]}"
122 +
123 + if [[ ${1} == -a ]] || has_version 'net-firewall/iptables[ipv6]'
124 + then
125 + printf -- '%s\n' "${IP6TABLES_SYMLINKS[@]}"
126 + fi
127 + ;;
128 + arptables) printf -- '%s\n' "${!ARPTABLES_SYMLINKS[@]}";;
129 + ebtables) printf -- '%s\n' "${!EBTABLES_SYMLINKS[@]}";;
130 + *) die "Invalid module name ${module}"
131 + esac
132 +}
133 +
134 +# get the symlink target given a symlink name and the target implementation
135 +get_symlink_target() {
136 + local link="${1}" target="${2}" module
137 + module="$(get_module)"
138 +
139 + case "${module}" in
140 + iptables) printf -- '%s\n' "${target}";;
141 + arptables)
142 + if [[ ${target} == *-legacy ]]; then
143 + printf -- '%s\n' "${ARPTABLES_SYMLINKS[${link}]}"
144 + else
145 + printf -- '%s\n' "${target}"
146 + fi
147 + ;;
148 + ebtables)
149 + if [[ ${target} == *-legacy ]]; then
150 + printf -- '%s\n' "${EBTABLES_SYMLINKS[${link}]}"
151 + else
152 + printf -- '%s\n' "${target}"
153 + fi
154 + ;;
155 + *) die "Invalid module name ${module}"
156 + esac
157 }
158
159 -# set the iptables symlink
160 +# set the symlinks for the current target
161 set_symlinks() {
162 local target="${1}"
163 + local retval=0
164
165 if is_number "${target}" && [[ ${target} -ge 1 ]]; then
166 local -a targets
167 - readarray -t targets <<< "$(find_targets)"
168 + readarray -t targets < <(find_targets)
169 target=${targets[$((target-1))]}
170 fi
171
172 @@ -46,130 +131,153 @@ set_symlinks() {
173 die -q "Target \"${target}\" doesn't appear to be valid!"
174 fi
175
176 - local ipt
177 - for ipt in "${IPTABLES_TARGETS[@]}"; do
178 - ln -s "${target}" "${EROOT}/sbin/${ipt}"
179 - done
180 + # create an array of symlinks to be created, then create them
181 + # in a separate pass, it's done this way in an attempt to be atomic
182 + # either all symlinks get updated, or none
183 + local -a symlinks_list
184 + readarray -t symlinks_list < <(get_symlinks_list)
185 +
186 + local symlink
187 + local -A do_symlinks
188 + for symlink in "${symlinks_list[@]}"; do
189 + local symlink_path="${EROOT}/sbin/${symlink}"
190 +
191 + if [[ -L ${symlink_path} || ! -e ${symlink_path} ]]; then
192 + do_symlinks["${symlink_path}"]="$(get_symlink_target "${symlink}" "${target}")"
193
194 - if [[ -n ${ipv6} ]]; then
195 - local ip6t
196 - for ip6t in "${IP6TABLES_TARGETS[@]}"; do
197 - ln -s "${target}" "${EROOT}/sbin/${ip6t}"
198 - done
199 - fi
200 + else
201 + die -q "Could not create symlink at ${symlink_path}:" \
202 + "path exits and is not a symlink"
203 + fi
204 + done
205 +
206 + for symlink in "${!do_symlinks[@]}"; do
207 + if ! ln -sfn "${do_symlinks["${symlink}"]}" "${symlink}"; then
208 + write_error_message "Failed to create symlink at ${symlink}"
209 + retval=1
210 + fi
211 + done
212 +
213 + return "${retval}"
214 }
215
216 ### show action ###
217
218 describe_show() {
219 - echo "Show the current iptables symlink"
220 + printf -- 'Show the current %s symlink\n' "$(get_module)"
221 }
222
223 do_show() {
224 - local ipv6
225 - if [[ -d ${EROOT}/var/lib/ip6tables ]]; then
226 - ipv6=1
227 - fi
228 - write_list_start "Current iptables symlinks:"
229 - local ipt all_unset=1
230 - for ipt in "${IPTABLES_TARGETS[@]}"; do
231 - if [[ -L ${EROOT}/sbin/${ipt} ]]; then
232 - local ipta
233 - ipta=$(canonicalise "${EROOT}/sbin/${ipt}")
234 - write_kv_list_entry "${ipt}" "${ipta%/}"
235 + local -a symlinks_list
236 + readarray -t symlinks_list < <(get_symlinks_list)
237 +
238 + local all_unset=1 symlink
239 + write_list_start "Current $(get_module) symlinks:"
240 + for symlink in "${symlinks_list[@]}"; do
241 + symlink_path="${EROOT}/sbin/${symlink}"
242 +
243 + if [[ -L ${symlink_path} ]]; then
244 + local symlink_target
245 + symlink_target=$(canonicalise "${symlink_path}")
246 + write_kv_list_entry "${symlink}" "${symlink_target%/}"
247 all_unset=0
248 - else
249 - write_kv_list_entry "${ipt}" "(unset)"
250 + elif [[ ! -f ${symlink_path} ]]; then
251 + write_kv_list_entry "${symlink}" "(unset)"
252 fi
253 done
254 - if [[ ${ipv6} -eq 1 ]]; then
255 - write_list_start "Current ip6tables symlinks:"
256 - local ip6t
257 - for ip6t in "${IP6TABLES_TARGETS[@]}"; do
258 - if [[ -L ${EROOT}/sbin/${ip6t} ]]; then
259 - local ipta
260 - ipta=$(canonicalise "${EROOT}/sbin/${ip6t}")
261 - write_kv_list_entry "${ip6t}" "${ipta%/}"
262 - all_unset=0
263 - else
264 - write_kv_list_entry "${ip6t}" "(unset)"
265 - fi
266 - done
267 - fi
268 +
269 return "${all_unset}"
270 }
271 ### list action ###
272
273 describe_list() {
274 - echo "List available iptables symlink targets"
275 + printf -- 'List available %s symlink targets\n' "$(get_module)"
276 }
277
278 do_list() {
279 - local ipv6
280 - local -a targets
281 - readarray -t targets <<< "$(find_targets)"
282 - if [[ -L ${EROOT}/var/lib/ip6tables ]]; then
283 - ipv6=1
284 - fi
285 - write_list_start "Available iptables symlink targets:"
286 - local i
287 - for (( i = 0; i < ${#targets[@]}; i++ )); do
288 - # highlight the target where the symlink is pointing to
289 - [[ ${targets[i]} = \
290 - $(basename "$(canonicalise "${EROOT}/sbin/iptables")") ]] \
291 - && targets[i]=$(highlight_marker "${targets[i]}")
292 + local module
293 + module="$(get_module)"
294 +
295 + local -a targets_list symlinks_list
296 + readarray -t targets_list < <(find_targets)
297 + readarray -t symlinks_list < <(get_symlinks_list)
298 +
299 + local -a targets_output
300 +
301 + write_list_start "Available ${module} symlink targets:"
302 + local symlink current_target
303 + for symlink in "${symlinks_list[@]}"; do
304 + local symlink_path="${EROOT}/sbin/${symlink}"
305 + local target
306 + for target in "${targets_list[@]}"; do
307 + local symlink_target resolved_target
308 + symlink_target="$(get_symlink_target "${symlink}" "${target}")"
309 + resolved_target="$(basename "$(canonicalise "${symlink_path}")")"
310 +
311 + if [[ ${resolved_target} == "${symlink_target}" ]]; then
312 + if [[ -z ${current_target} ]]; then
313 + current_target="${target}"
314 + break
315 + elif [[ ${current_target} != "${target}" ]]; then
316 + write_warning_msg "Target mismatch"
317 + unset current_target
318 + break 2
319 + fi
320 + fi
321 + done
322 + done
323 + for target in "${targets_list[@]}"; do
324 + if [[ ${target} == "${current_target}" ]]; then
325 + targets_output+=("$(highlight_marker "${target}")")
326 + else
327 + targets_output+=("${target}")
328 + fi
329 done
330 - write_numbered_list -m "(none found)" "${targets[@]}"
331 +
332 + write_numbered_list -m "(none found)" "${targets_output[@]}"
333 }
334
335 ### set action ###
336
337 describe_set() {
338 - echo "Set a new iptables symlink target"
339 -}
340 -
341 -describe_set_parameters() {
342 - echo "[--ipv6] <target>"
343 + printf "Set a new $(get_module) symlink target\\n"
344 }
345
346 describe_set_options() {
347 - echo "--ipv6: Forces creation of ip6tables symlinks"
348 - echo "target : Target name or number (from 'list' action)"
349 + printf -- "target : Target name or number (from 'list' action)\\n"
350 }
351
352 do_set() {
353 - local ipv6 ipv6_remove
354 - if [[ ${1} == "--ipv6" ]]; then
355 - ipv6=1
356 - shift
357 - fi
358 local target="${1}"
359
360 [[ -z ${target} ]] && die -q "You didn't tell me what to set the symlink to"
361 - [[ ${#} -gt 2 ]] && die -q "Too many parameters"
362 + [[ ${#} -gt 1 ]] && die -q "Too many parameters"
363
364 - if [[ -d ${EROOT}/var/lib/ip6tables ]]; then
365 - ipv6=1
366 - [[ -L ${EROOT}/sbin/ip6tables ]] && ipv6_remove=1
367 - fi
368 - if [[ -L ${EROOT}/sbin/iptables ]]; then
369 - # existing symlink
370 - remove_symlinks || die -q "Couldn't remove existing symlink"
371 - set_symlinks "${target}" || die -q "Couldn't set a new symlink"
372 - elif [[ -e ${EROOT}/sbin/iptables ]]; then
373 - # we have something strange
374 - die -q "${EROOT}/sbin/iptables exists but is not a symlink"
375 - else
376 - set_symlinks "${target}" || die -q "Couldn't set a new symlink"
377 - fi
378 + set_symlinks "${target}" || die -q "Couldn't set symlinks"
379 }
380
381 ### unset action ###
382
383 describe_unset() {
384 - echo "Unset iptables symlink targets"
385 + printf -- 'Unset %s symlink targets\n' "$(get_module)"
386 }
387
388 do_unset() {
389 - remove_symlinks
390 + local retval=0
391 +
392 + local -a symlinks_list
393 + readarray -t symlinks_list < <(get_symlinks_list -a)
394 +
395 + local symlink
396 + for symlink in "${symlinks_list[@]}"; do
397 + local symlink_path="${EROOT}/sbin/${symlink}"
398 + if [[ -L ${symlink_path} ]]; then
399 + unlink "${symlink_path}" || retval=${?}
400 + elif [[ -e ${symlink_path} ]]; then
401 + write_error_msg "Not removing non-symlink \"${symlink_path}\""
402 + retval=1
403 + fi
404 + done
405 +
406 + return ${retval}
407 }