From 2587acda28156f50149a15cad67d0c0bc1eb0bb4 Mon Sep 17 00:00:00 2001 From: Jouke Witteveen Date: Sun, 5 May 2013 23:07:06 +0200 Subject: Use pkg-config to obtain the systemd system unit directory This ensures the units are installed correctly if systemd is installed in an alternate location like /lib/systemd. Idem for the location of profile-based units. Based on a proposal by: Mike Gilbert --- src/netctl | 181 ---------------------------------------------------------- src/netctl.in | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+), 181 deletions(-) delete mode 100755 src/netctl create mode 100644 src/netctl.in (limited to 'src') diff --git a/src/netctl b/src/netctl deleted file mode 100755 index 4441838..0000000 --- a/src/netctl +++ /dev/null @@ -1,181 +0,0 @@ -#! /bin/bash - -. /usr/lib/network/globals - -NETCTL_VERSION=notpackaged - - -usage() { - cat << END -Usage: netctl {COMMAND} [PROFILE] - [--help|--version] - -Commands: - list List available profiles - store Save which profiles are active - restore Load saved profiles - stop-all Stops all profiles - start [PROFILE] Start a profile - stop [PROFILE] Stop a profile - restart [PROFILE] Restart a profile - switch-to [PROFILE] Switch to a profile - status [PROFILE] Show runtime status of a profile - enable [PROFILE] Enable the systemd unit for a profile - disable [PROFILE] Disable the systemd unit for a profile - reenable [PROFILE] Reenable the systemd unit for a profile -END -} - -sd_escape() { - local IFS='' - # Prevent a recursion loop on backspaces - set -- "${@//\\/\\x5c}" - while [[ "$*" =~ [^[:alnum:].:_/\\] ]]; do - set -- "${@//$BASH_REMATCH/$(printf '\\x%x' "'$BASH_REMATCH")}" - done - printf '%s\n' "${@//\//-}" -} - -# Wrapper around systemctl to convert profile names to unit names -sd_call() { - local command=$1 - shift - set -- $(sd_escape "$@") - systemctl $command $(printf 'netctl@%s.service\n' "$@") -} - -list() { - local indicators=( '*' ' ' ) - list_profiles | while read -r Profile; do - sd_call "is-active --quiet" "$Profile" &> /dev/null - # Make the return variable boolean - [[ $? -eq 0 ]]; printf '%s %s\n' "${indicators[$?]}" "$Profile" - done -} - -store() { - mkdir -p "$(dirname "$STATE_FILE")" - list_profiles | while read -r Profile; do - if sd_call "is-active --quiet" "$Profile" &> /dev/null; then - printf "%s\n" "$Profile" - fi - done > "$STATE_FILE" -} - -restore() { - if [[ ! -r $STATE_FILE ]]; then - exit_error "Could not read state file '$STATE_FILE'" - elif [[ ! -s $STATE_FILE ]]; then - report_debug "No profiles to restore in state file '$STATE_FILE'" - else - mapfile -t Profiles < "$STATE_FILE" - do_debug sd_call start "${Profiles[@]}" - fi -} - -stop_all() { - # We cannot pipe to mapfile, as the end of a pipe is inside a subshell - mapfile -t Profiles < <(list_profiles) - [[ $Profiles ]] && do_debug sd_call stop "${Profiles[@]}" 2> \ - >(grep -Fv "not loaded" >&2) -} - -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 < \ - <(grep -om1 "^[[:space:]]*Interface=[[:alnum:]:._-]\+" "$1") - if [[ -z $InterfaceLine ]]; then - exit_error "Profile '$1' does not specify an interface" - fi - mapfile -t AllProfiles < <(list_profiles) - mapfile -t Profiles < <(grep -Fl "$InterfaceLine" "${AllProfiles[@]}") - [[ $Profiles ]] && do_debug sd_call stop "${Profiles[@]}" 2> \ - >(grep -Fv "not loaded" >&2) - do_debug sd_call start "$1" -} - -unit_enable() { - local unit="/etc/systemd/system/netctl@$(sd_escape "$1").service" - if [[ -e $unit ]]; then - report_error "A unit file for profile '$1' already exists" - return 1 - fi - load_profile "$1" - echo ".include /usr/lib/systemd/system/netctl@.service" > "$unit" - echo -e "\n[Unit]" >> "$unit" - [[ -n $Description ]] && echo "Description=$Description" >> "$unit" - if [[ -n ${BindsToInterfaces=$Interface} ]]; then - : ${InterfaceRoot=sys/subsystem/net/devices/} - printf "BindsTo=$(sd_escape "$InterfaceRoot")%s.device\n" \ - $(sd_escape "${BindsToInterfaces[@]}") >> "$unit" - printf "After=$(sd_escape "$InterfaceRoot")%s.device\n" \ - $(sd_escape "${BindsToInterfaces[@]}") >> "$unit" - fi - if [[ -n $After ]]; then - printf 'After="netctl@%s.service"\n' \ - $(sd_escape "${After[@]}") >> "$unit" - fi - echo "ln -s '$unit' '${unit/system\//system/multi-user.target.wants/}'" - ln -s "$unit" "${unit/system\//system/multi-user.target.wants/}" - systemctl daemon-reload -} - -unit_disable() { - local unit="/etc/systemd/system/netctl@$(sd_escape "$1").service" - if sd_call "is-enabled --quiet" "$1" &> /dev/null; then - sd_call disable "$1" - fi - if [[ ! -f $unit ]]; then - report_error "No regular unit file found for profile '$1'" - return 1 - fi - do_debug rm "$unit" - systemctl daemon-reload -} - - -case $# in - 1) - case $1 in - --version) - report_notice "netctl version $NETCTL_VERSION";; - --help) - usage;; - list) - list;; - store|restore) - ensure_root "$(basename "$0")" - "$1";; - stop-all) - stop_all;; - *) - exit_error "$(usage)";; - esac;; - 2) - case $1 in - start|stop|restart|status) - sd_call "$1" "$2";; - switch-to) - ensure_root "$(basename "$0")" - switch_to "$2";; - enable|disable) - ensure_root "$(basename "$0")" - "unit_$1" "$2";; - reenable) - ensure_root "$(basename "$0")" - unit_disable "$2" - unit_enable "$2";; - *) - exit_error "$(usage)";; - esac;; - *) - exit_error "$(usage)";; -esac - - -# vim: ft=sh ts=4 et sw=4: diff --git a/src/netctl.in b/src/netctl.in new file mode 100644 index 0000000..2d04d28 --- /dev/null +++ b/src/netctl.in @@ -0,0 +1,181 @@ +#! /bin/bash + +. /usr/lib/network/globals + +NETCTL_VERSION=notpackaged + + +usage() { + cat << END +Usage: netctl {COMMAND} [PROFILE] + [--help|--version] + +Commands: + list List available profiles + store Save which profiles are active + restore Load saved profiles + stop-all Stops all profiles + start [PROFILE] Start a profile + stop [PROFILE] Stop a profile + restart [PROFILE] Restart a profile + switch-to [PROFILE] Switch to a profile + status [PROFILE] Show runtime status of a profile + enable [PROFILE] Enable the systemd unit for a profile + disable [PROFILE] Disable the systemd unit for a profile + reenable [PROFILE] Reenable the systemd unit for a profile +END +} + +sd_escape() { + local IFS='' + # Prevent a recursion loop on backspaces + set -- "${@//\\/\\x5c}" + while [[ "$*" =~ [^[:alnum:].:_/\\] ]]; do + set -- "${@//$BASH_REMATCH/$(printf '\\x%x' "'$BASH_REMATCH")}" + done + printf '%s\n' "${@//\//-}" +} + +# Wrapper around systemctl to convert profile names to unit names +sd_call() { + local command=$1 + shift + set -- $(sd_escape "$@") + systemctl $command $(printf 'netctl@%s.service\n' "$@") +} + +list() { + local indicators=( '*' ' ' ) + list_profiles | while read -r Profile; do + sd_call "is-active --quiet" "$Profile" &> /dev/null + # Make the return variable boolean + [[ $? -eq 0 ]]; printf '%s %s\n' "${indicators[$?]}" "$Profile" + done +} + +store() { + mkdir -p "$(dirname "$STATE_FILE")" + list_profiles | while read -r Profile; do + if sd_call "is-active --quiet" "$Profile" &> /dev/null; then + printf "%s\n" "$Profile" + fi + done > "$STATE_FILE" +} + +restore() { + if [[ ! -r $STATE_FILE ]]; then + exit_error "Could not read state file '$STATE_FILE'" + elif [[ ! -s $STATE_FILE ]]; then + report_debug "No profiles to restore in state file '$STATE_FILE'" + else + mapfile -t Profiles < "$STATE_FILE" + do_debug sd_call start "${Profiles[@]}" + fi +} + +stop_all() { + # We cannot pipe to mapfile, as the end of a pipe is inside a subshell + mapfile -t Profiles < <(list_profiles) + [[ $Profiles ]] && do_debug sd_call stop "${Profiles[@]}" 2> \ + >(grep -Fv "not loaded" >&2) +} + +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 < \ + <(grep -om1 "^[[:space:]]*Interface=[[:alnum:]:._-]\+" "$1") + if [[ -z $InterfaceLine ]]; then + exit_error "Profile '$1' does not specify an interface" + fi + mapfile -t AllProfiles < <(list_profiles) + mapfile -t Profiles < <(grep -Fl "$InterfaceLine" "${AllProfiles[@]}") + [[ $Profiles ]] && do_debug sd_call stop "${Profiles[@]}" 2> \ + >(grep -Fv "not loaded" >&2) + do_debug sd_call start "$1" +} + +unit_enable() { + local unit="@systemdsystemconfdir@/netctl@$(sd_escape "$1").service" + if [[ -e $unit ]]; then + report_error "A unit file for profile '$1' already exists" + return 1 + fi + load_profile "$1" + echo ".include @systemdsystemunitdir@/netctl@.service" > "$unit" + echo -e "\n[Unit]" >> "$unit" + [[ -n $Description ]] && echo "Description=$Description" >> "$unit" + if [[ -n ${BindsToInterfaces=$Interface} ]]; then + : ${InterfaceRoot=sys/subsystem/net/devices/} + printf "BindsTo=$(sd_escape "$InterfaceRoot")%s.device\n" \ + $(sd_escape "${BindsToInterfaces[@]}") >> "$unit" + printf "After=$(sd_escape "$InterfaceRoot")%s.device\n" \ + $(sd_escape "${BindsToInterfaces[@]}") >> "$unit" + fi + if [[ -n $After ]]; then + printf 'After="netctl@%s.service"\n' \ + $(sd_escape "${After[@]}") >> "$unit" + fi + echo "ln -s '$unit' '${unit/system\//system/multi-user.target.wants/}'" + ln -s "$unit" "${unit/system\//system/multi-user.target.wants/}" + systemctl daemon-reload +} + +unit_disable() { + local unit="@systemdsystemconfdir@/netctl@$(sd_escape "$1").service" + if sd_call "is-enabled --quiet" "$1" &> /dev/null; then + sd_call disable "$1" + fi + if [[ ! -f $unit ]]; then + report_error "No regular unit file found for profile '$1'" + return 1 + fi + do_debug rm "$unit" + systemctl daemon-reload +} + + +case $# in + 1) + case $1 in + --version) + report_notice "netctl version $NETCTL_VERSION";; + --help) + usage;; + list) + list;; + store|restore) + ensure_root "$(basename "$0")" + "$1";; + stop-all) + stop_all;; + *) + exit_error "$(usage)";; + esac;; + 2) + case $1 in + start|stop|restart|status) + sd_call "$1" "$2";; + switch-to) + ensure_root "$(basename "$0")" + switch_to "$2";; + enable|disable) + ensure_root "$(basename "$0")" + "unit_$1" "$2";; + reenable) + ensure_root "$(basename "$0")" + unit_disable "$2" + unit_enable "$2";; + *) + exit_error "$(usage)";; + esac;; + *) + exit_error "$(usage)";; +esac + + +# vim: ft=sh ts=4 et sw=4: -- cgit v1.2.3-24-g4f1b