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 --- Makefile | 33 ++++++---- contrib/PKGBUILD | 35 ---------- contrib/PKGBUILD.in | 36 +++++++++++ src/netctl | 181 ---------------------------------------------------- src/netctl.in | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 238 insertions(+), 228 deletions(-) delete mode 100644 contrib/PKGBUILD create mode 100644 contrib/PKGBUILD.in delete mode 100755 src/netctl create mode 100644 src/netctl.in diff --git a/Makefile b/Makefile index bf48aa5..2fcf62b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,11 @@ export VERSION = 1.0 +PKG_CONFIG ?= pkg-config + +sd_var = $(shell $(PKG_CONFIG) --variable=systemd$(1) systemd) +systemdsystemconfdir = $(call sd_var,systemconfdir) +systemdsystemunitdir = $(call sd_var,systemunitdir) + .PHONY: install tarball pkgbuild clean install: @@ -15,35 +21,38 @@ install: install -m755 src/lib/{auto.action,network} $(DESTDIR)/usr/lib/network/ # Scripts install -d $(DESTDIR)/usr/bin + sed -e "s|@systemdsystemconfdir@|$(systemdsystemconfdir)|g" \ + -e "s|@systemdsystemunitdir@|$(systemdsystemunitdir)|g" \ + src/netctl.in > $(DESTDIR)/usr/bin/netctl + chmod 755 $(DESTDIR)/usr/bin/netctl install -m755 \ - src/netctl \ src/netctl-auto \ src/wifi-menu \ $(DESTDIR)/usr/bin/ install -Dm755 src/ifplugd.action $(DESTDIR)/etc/ifplugd/netctl.action # Services - install -d $(DESTDIR)/usr/lib/systemd/system - install -m644 services/*.service $(DESTDIR)/usr/lib/systemd/system/ + install -d $(DESTDIR)$(systemdsystemunitdir) + install -m644 services/*.service $(DESTDIR)$(systemdsystemunitdir)/ tarball: netctl-$(VERSION).tar.xz netctl-$(VERSION).tar.xz: $(MAKE) -B -C docs - cp src/netctl{,.orig} - sed -i "s/NETCTL_VERSION=.*/NETCTL_VERSION=$(VERSION)/" src/netctl + cp src/netctl.in{,.orig} + sed -i "s|NETCTL_VERSION=.*|NETCTL_VERSION=$(VERSION)|" src/netctl.in git stash save -q git archive -o netctl-$(VERSION).tar --prefix=netctl-$(VERSION)/ stash git stash pop -q - mv src/netctl{.orig,} - tar --exclude-vcs --transform "s%^%netctl-$(VERSION)/%" --owner=root --group=root --mtime=./netctl-$(VERSION).tar -rf netctl-$(VERSION).tar docs/*.[1-8] + mv src/netctl.in{.orig,} + tar --exclude-vcs --transform "s|^|netctl-$(VERSION)/|" --owner=root --group=root --mtime=./netctl-$(VERSION).tar -rf netctl-$(VERSION).tar docs/*.[1-8] xz netctl-$(VERSION).tar gpg --detach-sign $@ pkgbuild: PKGBUILD -PKGBUILD: netctl-$(VERSION).tar.xz - sed -e "s/%pkgver%/$(VERSION)/g" \ - -e "s/%md5sum%/$(shell md5sum $< | cut -d ' ' -f 1)/" \ - -e "s/%md5sum.sig%/$(shell md5sum $<.sig | cut -d ' ' -f 1)/" \ - contrib/PKGBUILD > $@ +PKGBUILD: netctl-$(VERSION).tar.xz contrib/PKGBUILD.in + sed -e "s|@pkgver@|$(VERSION)|g" \ + -e "s|@md5sum@|$(shell md5sum $< | cut -d ' ' -f 1)|" \ + -e "s|@md5sum.sig@|$(shell md5sum $<.sig | cut -d ' ' -f 1)|" \ + $(lastword $^) > $@ upload: netctl-$(VERSION).tar.xz scp $< $<.sig nymeria.archlinux.org:/srv/ftp/other/packages/netctl diff --git a/contrib/PKGBUILD b/contrib/PKGBUILD deleted file mode 100644 index 0190048..0000000 --- a/contrib/PKGBUILD +++ /dev/null @@ -1,35 +0,0 @@ -# Maintainer: Jouke Witteveen - -pkgname=netctl -pkgver=%pkgver% -pkgrel=1 -pkgdesc='Profile based systemd network management' -url='http://projects.archlinux.org/netctl.git/' -license=('GPL') -groups=('base') -depends=('coreutils' 'iproute2' 'openresolv') -#makedepends=('asciidoc') # The source tarball includes pre-built documentation. -optdepends=('dialog: for the menu based wifi assistant' - 'dhclient: for DHCP support (or dhcpcd)' - 'dhcpcd: for DHCP support (or dhclient)' - 'wpa_supplicant: for wireless networking support' - 'ifplugd: for automatic wired connections through netctl-ifplugd' - 'wpa_actiond: for automatic wireless connections through netctl-auto' - 'ifenslave: for bond connections' - 'bridge-utils: for bridge connections' - 'ppp: for pppoe connections' - ) -source=(ftp://ftp.archlinux.org/other/packages/netctl/netctl-${pkgver}.tar.xz{,.sig}) -arch=('any') -md5sums=('%md5sum%' - '%md5sum.sig%') - -package() { - cd "$srcdir/netctl-${pkgver}" - make DESTDIR="$pkgdir" install - - # Shell Completion - install -D -m644 contrib/bash-completion "$pkgdir/usr/share/bash-completion/completions/netctl" - install -D -m644 contrib/zsh-completion "$pkgdir/usr/share/zsh/site-functions/_netctl" -} - diff --git a/contrib/PKGBUILD.in b/contrib/PKGBUILD.in new file mode 100644 index 0000000..3c7b9b0 --- /dev/null +++ b/contrib/PKGBUILD.in @@ -0,0 +1,36 @@ +# Maintainer: Jouke Witteveen + +pkgname=netctl +pkgver=@pkgver@ +pkgrel=1 +pkgdesc='Profile based systemd network management' +url='http://projects.archlinux.org/netctl.git/' +license=('GPL') +groups=('base') +depends=('coreutils' 'iproute2' 'openresolv') +# The source tarball includes pre-built (using asciidoc) documentation. +makedepends=('pkg-config') +optdepends=('dialog: for the menu based wifi assistant' + 'dhclient: for DHCP support (or dhcpcd)' + 'dhcpcd: for DHCP support (or dhclient)' + 'wpa_supplicant: for wireless networking support' + 'ifplugd: for automatic wired connections through netctl-ifplugd' + 'wpa_actiond: for automatic wireless connections through netctl-auto' + 'ifenslave: for bond connections' + 'bridge-utils: for bridge connections' + 'ppp: for pppoe connections' + ) +source=(ftp://ftp.archlinux.org/other/packages/netctl/netctl-${pkgver}.tar.xz{,.sig}) +arch=('any') +md5sums=('@md5sum@' + '@md5sum.sig@') + +package() { + cd "$srcdir/netctl-${pkgver}" + make DESTDIR="$pkgdir" install + + # Shell Completion + install -D -m644 contrib/bash-completion "$pkgdir/usr/share/bash-completion/completions/netctl" + install -D -m644 contrib/zsh-completion "$pkgdir/usr/share/zsh/site-functions/_netctl" +} + 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