Commit 8773d7f0 authored by Jouke Witteveen's avatar Jouke Witteveen
Browse files

More uniform profile loading and filtering

Hooks and interface scripts are now sourced more systematically.
Settings of wireless profiles that depend on hooks are now picked up
correctly by netctl-auto.

Suggested by: Vitor Sakaguti <vis@tutao.de>
parent 9b70046f
......@@ -14,11 +14,10 @@ case "$2" in
printf '%s' "$profile" > "$PROFILE_FILE"
exit 0
fi
done < <(list_profiles | while IFS= read -r profile; do
done < <(filter_profiles "$1" ethernet | while IFS= read -r profile; do
report_debug "Examining profile '$profile'"
(
source "$PROFILE_DIR/$profile" > /dev/null
[[ $Interface == "$1" && $Connection == "ethernet" ]] || exit
load_profile "$profile" > /dev/null
# Prioritize dhcp based profiles as they can outright fail, whereas
# it is difficult to tell if a profile with a static address fails
if [[ $IP == "dhcp" || $IP6 == dhcp* ]]; then
......
#! /bin/bash
. /usr/lib/netctl/globals
. "$SUBR_DIR/interface"
. "$SUBR_DIR/ip"
export INTERFACE="$1"
......@@ -11,7 +10,6 @@ PROFILE_FILE="$STATE_DIR/netctl-auto-$INTERFACE.profile"
case $ACTION in
CONNECTED)
load_profile "$WPA_ID_STR"
load_interface_config "$INTERFACE"
DhcpcdOptions+=" -K -L"
ip_set || exit 1
mkdir -p "$(dirname "$PROFILE_FILE")"
......@@ -26,7 +24,6 @@ case $ACTION in
DISCONNECTED)
if [[ -s "$PROFILE_FILE" ]]; then
load_profile "$(< "$PROFILE_FILE")"
load_interface_config "$INTERFACE"
rm -f "$PROFILE_FILE"
# Sandbox the eval
if ! ( do_debug eval "$ExecDownPre" ); then
......
......@@ -103,41 +103,71 @@ timeout_wait() {
### Profile management
## List all acceptable profiles names separated by newlines
list_profiles() {
# Follow aliases with -L, skip forbidden/reserved names
find -L "$PROFILE_DIR/" -maxdepth 1 -type f -not -name '.*' -not -name '*~' -not -name $'*\n*' -not -name '*.action' -not -name '*.conf' -not -name '*.service' -printf '%f\n'
## Load all available hooks
load_hooks() {
local hook
while IFS= read -r hook; do
source "$hook"
done < <(find -L "$PROFILE_DIR/hooks" -maxdepth 1 -type f -executable -not -name '.*' -not -name '*~' -not -name $'*\n*' | sort)
}
## Exit if a profile file is not syntactically correct
# $1: profile name
verify_profile() {
/bin/bash -n "$PROFILE_DIR/$1" || exit 1
## Load interface configuration, if present
# $1: interface name
load_interface_config() {
local config_file="$PROFILE_DIR/interfaces/$1"
if [[ -x $config_file ]]; then
source "$config_file"
fi
}
## Sources all hooks and a profile (but no interface configuration)
# $1: profile name
load_profile() {
local hook
# Expose the profile name
Profile=$1
if [[ -z $Profile || ! -r "$PROFILE_DIR/$Profile" ]]; then
exit_error "Profile '$Profile' does not exist or is not readable"
fi
while IFS= read -r hook; do
source "$hook"
done < <(find -L "$PROFILE_DIR/hooks" -maxdepth 1 -type f -executable -not -name '.*' -not -name '*~' -not -name $'*\n*' | sort -u)
unset hook
load_hooks
source "$PROFILE_DIR/$Profile"
if [[ -z $Interface ]]; then
exit_error "Profile '$Profile' does not specify an interface"
fi
load_interface_config "$Interface"
if [[ ! -r "${Connection:+$SUBR_DIR/connections/$Connection}" ]]; then
exit_error "Profile '$Profile' does not specify a valid connection"
fi
source "$SUBR_DIR/connections/$Connection"
}
## List all acceptable profiles names separated by newlines
list_profiles() {
# Follow aliases with -L, skip forbidden/reserved names
find -L "$PROFILE_DIR/" -maxdepth 1 -type f -not -name '.*' -not -name '*~' -not -name $'*\n*' -not -name '*.action' -not -name '*.conf' -not -name '*.service' -printf '%f\n'
}
## List names of profiles for a given interface and/or connection
# $1: interface (optional)
# $2: connection (optional)
filter_profiles() {
list_profiles | while IFS= read -r Profile; do
if (
source "$PROFILE_DIR/$Profile" &> /dev/null
[[ $Interface && ( -z $1 || $1 == "$Interface" ) ]] || exit
load_interface_config "$Interface" > /dev/null
[[ $Connection && ( -z $2 || $2 == "$Connection" ) ]] || exit
); then
printf '%s\n' "$Profile"
fi
done
}
## Exit if a profile file is not syntactically correct
# $1: profile name
verify_profile() {
/bin/bash -n "$PROFILE_DIR/$1" || exit 1
}
## Wrapper around systemctl converting profile names to unit names
# $1: systemctl command
# $2...: profile names
......
## /usr/lib/netctl/globals needs to be sourced before this file
## Load interface configuration, if present
# $1: interface name
load_interface_config() {
local config_file="$PROFILE_DIR/interfaces/$1"
if [[ -x $config_file ]]; then
source "$config_file"
fi
}
## Check if a string represents a network interface
# $1: potential interface name
is_interface() {
......
......@@ -88,7 +88,6 @@ elif [[ $# -eq 2 && $1 == @(start|stop) ]]; then
# Expose the command
Command=$1
load_profile "$2"
load_interface_config "$Interface"
"network_$1"
else
exit_error "Usage: $0 {start|stop|wait-online} [profile]"
......
......@@ -211,12 +211,10 @@ start() {
# Disable p2p to prevent wpa_supplicant from creating another control interface
echo "p2p_disabled=1" >> "$WPAConfigFile"
local profile
list_profiles | while IFS= read -r profile; do
filter_profiles "$interface" wireless | while IFS= read -r profile; do
report_debug "Examining profile '$profile'"
(
source "$PROFILE_DIR/$profile"
[[ $Interface == "$interface" && $Connection == "wireless" ]] || exit
load_profile "$profile"
is_yes "${ExcludeAuto:-no}" && exit
# Set default and exclude wpa-config as it does not fit this scheme
[[ ${Security:=none} != "wpa-config" ]] || exit
......
......@@ -71,16 +71,11 @@ stop_all() {
}
switch_to() {
cd "$PROFILE_DIR"
# We assume interface names are not quoted
# Using read removes leading whitespace
read InterfaceLine < \
<(grep -om1 '^[[:space:]]*Interface=[[:alnum:]:._-]\+' "$1")
if [[ -z $InterfaceLine ]]; then
Interface=$(. "$PROFILE_DIR/$1" >/dev/null; printf '%s' "$Interface")
if [[ -z $Interface ]]; then
exit_error "Profile '$1' does not specify an interface"
fi
mapfile -t AllProfiles < <(list_profiles)
mapfile -t Profiles < <(grep -Fl "$InterfaceLine" "${AllProfiles[@]}")
mapfile -t Profiles < <(filter_profiles "$Interface")
if (( ${#Profiles[@]} )); then
do_debug sd_call stop "${Profiles[@]}" 2> >(grep -Fv 'not loaded' >&2)
fi
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment