The name of the subcommand mirrors the same subcommand of systemd-analyze. Verification before restarting would be useful. However, verification requires the profile file to be readable by the current user. The current user may be a regular user with permission to control systemd, so restarting does not require the profile file to be readable. Therefore, we do not attempt verification before restarting. --- docs/netctl.1.txt | 6 +++++- src/lib/globals | 6 ++++++ src/netctl.in | 26 ++++++++++++++------------ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/netctl.1.txt b/docs/netctl.1.txt index d6d9360..76d45b0 100644 --- a/docs/netctl.1.txt +++ b/docs/netctl.1.txt @@ -82,7 +82,11 @@ The following commands are understood: *edit [+PROFILE+]*:: Open the file of the specified profile in an editor. This does not - reenable or restart any profiles. + reenable, restart, or verify any profiles. + +*verify [+PROFILE+]*:: + Check the file of the specified profile for syntax errors. If no + errors are found, no output is produced. *wait-online [+PROFILE+]*:: Wait until the interface of the profile has a routable IP address of diff --git a/src/lib/globals b/src/lib/globals index 74ce623..32a1802 100644 --- a/src/lib/globals +++ b/src/lib/globals @@ -109,6 +109,12 @@ list_profiles() { 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' } +## Exit if a profile file is not syntactically correct +# $1: profile name +verify_profile() { + /bin/bash -n "$PROFILE_DIR/$1" || exit 1 +} + ## Sources all hooks and a profile (but no interface configuration) # $1: profile name load_profile() { diff --git a/src/netctl.in b/src/netctl.in index c1ed493..a580048 100644 --- a/src/netctl.in +++ b/src/netctl.in @@ -23,7 +23,8 @@ Commands: disable [PROFILE] Disable the systemd unit for a profile reenable [PROFILE] Reenable the systemd unit for a profile is-enabled [PROFILE] Check whether a profile is enabled - edit [PROFILE] Edit a profile + edit [PROFILE] Edit a profile file + verify [PROFILE] Check the syntax of a profile file wait-online [PROFILE] Wait for a profile to finish connecting END } @@ -71,9 +72,6 @@ stop_all() { switch_to() { cd "$PROFILE_DIR" - if [[ ! -r $1 ]]; then - exit_error "Profile '$1' does not exist or is not readable" - fi # We assume interface names are not quoted # Using read removes leading whitespace read InterfaceLine < \ @@ -129,6 +127,11 @@ unit_disable() { "@systemdsystemconfdir@/$unit.d"{/profile.conf,} } +unit_reenable() { + unit_disable "$1" + unit_enable "$1" +} + wait_online() { local profile="$1" if sd_call "is-active --quiet" "$profile"; then @@ -163,20 +166,19 @@ case $# in sd_call "$1" "$2";; switch-to) ensure_root "$(basename "$0")" + verify_profile "$2" switch_to "$2";; - enable|disable) + enable|disable|reenable) ensure_root "$(basename "$0")" + if [[ $1 != "disable" ]]; then + verify_profile "$2" + fi "unit_$1" "$2" if systemd-notify --booted; then systemctl daemon-reload fi;; - reenable) - ensure_root "$(basename "$0")" - unit_disable "$2" - unit_enable "$2" - if systemd-notify --booted; then - systemctl daemon-reload - fi;; + verify) + verify_profile "$2";; edit) exec ${EDITOR:-nano} "$PROFILE_DIR/$2";; wait-online) -- 2.30.0