forked from ungleich-public/cdist
		
	[type/__uci_section] Improve --match support with existing named sections
Use section if named section exists without --match option (e.g. empty section).
This commit is contained in:
		
					parent
					
						
							
								4aebb1f127
							
						
					
				
			
			
				commit
				
					
						63d41a1053
					
				
			
		
					 1 changed files with 51 additions and 29 deletions
				
			
		| 
						 | 
					@ -20,62 +20,84 @@
 | 
				
			||||||
# This explorer determines the "prefix" of the --type section matching --match
 | 
					# This explorer determines the "prefix" of the --type section matching --match
 | 
				
			||||||
# if set, or __object_id otherwise.
 | 
					# if set, or __object_id otherwise.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RS=$(printf '\036')
 | 
				
			||||||
 | 
					NL=$(printf '\n '); NL=${NL% }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
squote_values() {
 | 
					squote_values() {
 | 
				
			||||||
	sed -e '/=".*"$/{s/="/='\''/;s/"$/'\''/}' \
 | 
						sed -e '/=".*"$/{s/="/='\''/;s/"$/'\''/}' \
 | 
				
			||||||
	    -e "/='.*'$/"'!{s/=/='\''/;s/$/'\''/}'
 | 
						    -e "/='.*'$/"'!{s/=/='\''/;s/$/'\''/}'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					count_lines() (
 | 
				
			||||||
 | 
						IFS=${NL?}
 | 
				
			||||||
 | 
						# shellcheck disable=SC2048,SC2086
 | 
				
			||||||
 | 
						set -f -- $*; echo $#
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RS=$(printf '\036')
 | 
					echo "${__object_id:?}" | grep -q -e '^[^.]\{1,\}\.[^.]\{1,\}$' || {
 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! test -e "${__object:?}/parameter/match"
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
	if ! echo "${__object_id:?}" | grep -q -e '^[^.]\{1,\}\.[^.]\{1,\}$'
 | 
					 | 
				
			||||||
	then
 | 
					 | 
				
			||||||
	echo 'Section identifiers are a package and section name separated by a "." (period).' >&2
 | 
						echo 'Section identifiers are a package and section name separated by a "." (period).' >&2
 | 
				
			||||||
	exit 1
 | 
						exit 1
 | 
				
			||||||
	fi
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test -s "${__object:?}/parameter/match" || {
 | 
				
			||||||
	# If no --match is given, we take the __object_id as the section identifier.
 | 
						# If no --match is given, we take the __object_id as the section identifier.
 | 
				
			||||||
	echo "${__object_id:?}"
 | 
						echo "${__object_id:?}"
 | 
				
			||||||
	exit 0
 | 
						exit 0
 | 
				
			||||||
fi
 | 
					}
 | 
				
			||||||
 | 
					test -s "${__object:?}/parameter/type" || {
 | 
				
			||||||
# shellcheck disable=SC2015
 | 
					 | 
				
			||||||
test -s "${__object:?}/parameter/match" && test -s "${__object:?}/parameter/type" \
 | 
					 | 
				
			||||||
|| {
 | 
					 | 
				
			||||||
	echo 'Parameters --match and --type must be used together.' >&2
 | 
						echo 'Parameters --match and --type must be used together.' >&2
 | 
				
			||||||
	exit 1
 | 
						exit 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Find by match
 | 
					sect_type_param=$(cat "${__object:?}/parameter/type")
 | 
				
			||||||
# NOTE: Apart from section types all values are printed in single quotes by UCI.
 | 
					expr "${sect_type_param}" : '[^.]\{1,\}\.[^.]\{1,\}$' >/dev/null 2>&1 || {
 | 
				
			||||||
match=$(head -n 1 "${__object:?}/parameter/match" | squote_values)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! grep -q -e '^[^.]\{1,\}\.[^.]\{1,\}$' "${__object:?}/parameter/type"
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
	echo 'Section types are a package name and section type separated by a "." (period).' >&2
 | 
						echo 'Section types are a package name and section type separated by a "." (period).' >&2
 | 
				
			||||||
	exit 1
 | 
						exit 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					package_filter=${sect_type_param%%.*}
 | 
				
			||||||
 | 
					section_filter=${sect_type_param#*.}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Find by --match
 | 
				
			||||||
 | 
					# NOTE: Apart from section types all values are printed in single quotes by uci show.
 | 
				
			||||||
 | 
					match=$(head -n 1 "${__object:?}/parameter/match" | squote_values)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if uci -s -N get "${__object_id:?}" >/dev/null 2>&1
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						# Named section exists: ensure if --match applies to it
 | 
				
			||||||
 | 
						# if the "matched" option does not exist (e.g. empty section) we use the
 | 
				
			||||||
 | 
						# section unconditionally.
 | 
				
			||||||
 | 
						if match_value_is=$(uci -s -N get "${__object_id:?}.${match%%=*}" 2>/dev/null)
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							match_value_should=$(expr "${match}" : ".*='\\(.*\\)'$")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							test "${match_value_is}" = "${match_value_should}" || {
 | 
				
			||||||
 | 
								printf 'Named section "%s" does not match --match "%s"\n' \
 | 
				
			||||||
 | 
									   "${__object_id:?}" "${match}" >&2
 | 
				
			||||||
 | 
								exit 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sect_type_filter=$(cat "${__object:?}/parameter/type")
 | 
						echo "${__object_id:?}"
 | 
				
			||||||
package_filter=${sect_type_filter%%.*}
 | 
						exit 0
 | 
				
			||||||
section_filter=${sect_type_filter#*.}
 | 
					fi
 | 
				
			||||||
# FIXME: Does not work with named sections
 | 
					
 | 
				
			||||||
regex="^${package_filter}\.@${section_filter}\[[0-9]\{1,\}\]\.${match%%=*}="
 | 
					# No correctly named section exists already: find one to which --match applies
 | 
				
			||||||
 | 
					regex="^${package_filter}\\.@${section_filter}\\[[0-9]\\{1,\\}\\]\\.${match%%=*}="
 | 
				
			||||||
 | 
					
 | 
				
			||||||
matched_sections=$(
 | 
					matched_sections=$(
 | 
				
			||||||
	uci -s -N -d "${RS}" show "${package_filter}" 2>/dev/null \
 | 
						uci -s -N -d "${RS}" show "${package_filter}" 2>/dev/null \
 | 
				
			||||||
	| grep -e "${regex}" \
 | 
						| grep -e "${regex}" \
 | 
				
			||||||
	| while read -r _line
 | 
						| while read -r _line
 | 
				
			||||||
	  do
 | 
						  do
 | 
				
			||||||
		  if test "${_line#*=}" = "${match#*=}"; then echo "${_line}"; fi
 | 
							  if test "${_line#*=}" = "${match#*=}"
 | 
				
			||||||
 | 
							  then
 | 
				
			||||||
 | 
								  echo "${_line}"
 | 
				
			||||||
 | 
							  fi
 | 
				
			||||||
	  done \
 | 
						  done \
 | 
				
			||||||
	| sed -e 's/\.[^.]*=.*$//')
 | 
						| sed -e 's/\.[^.]*=.*$//')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if test "$(echo "${matched_sections}" | wc -l)" -gt 1
 | 
					test "$(count_lines "${matched_sections}")" -le 1 || {
 | 
				
			||||||
then
 | 
					 | 
				
			||||||
	printf 'Found multiple matching sections:\n%s\n' "${matched_sections}" >&2
 | 
						printf 'Found multiple matching sections:\n%s\n' "${matched_sections}" >&2
 | 
				
			||||||
	exit 1
 | 
						exit 1
 | 
				
			||||||
fi
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "${matched_sections}"
 | 
					echo "${matched_sections}"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue