make dependency require manual install
[newns] / newns
diff --git a/newns b/newns
index 5075181714569a1d6e8980bb27af27e0b3eb4ddc..315c786062d45295994cbb82e85cc2559aaa6053 100755 (executable)
--- a/newns
+++ b/newns
 
 [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
 
-tmp="$(readlink -f "${BASH_SOURCE}")"; script_dir="${tmp%/*}"
-if [[ ! $ERRHANDLE_PATH ]]; then
-  ERRHANDLE_PATH="$script_dir"/../errhandle/err
-fi
-if [[ -s $ERRHANDLE_PATH ]]; then
-  source $ERRHANDLE_PATH
-else
-  cd "$script_dir"
-  if ! wget -O err 'https://iankelling.org/git/?p=errhandle;a=blob_plain;f=err;hb=HEAD'; then
-    echo "$0: failed to get errhandle dependency" >&2
-    exit 1
-  fi
-  source err
-fi
+# https://savannah.nongnu.org/projects/bash-bear-trap/
+set -e; . /usr/local/lib/bash-bear; set +e
+
 
 usage() {
   cat <<EOF
@@ -38,7 +27,7 @@ Nat a network namespace. systemd friendly
 
 Also creates a mount namespace with a cloned /run/resolvconf.
 
--c, --create    Create a named network namespace. When running from
+-c, --create    Create or destroy a named network namespace. When running from
                 the same network namespace as pid 1, this is set automatically.
                 A systemd created private network is in a network namespace
                 different than pid 1.
@@ -60,9 +49,9 @@ From within a systemd network namespace, we nat it to the outside. This
 would be called from ExecStartPre, and or subsequent units called with
 JoinsNamespaceOf= and PrivateNetwork=true.
 
-We also create a named mount namespace under /root/mount_namespaces, so we
-can alter some system config for this namespace. systemd
-command lines would be prefixed with:
+If resolvconf is installed, we create a named mount namespace under
+/root/mount_namespaces, so we can alter some system config for this
+namespace. systemd command lines would be prefixed with:
 
 /usr/bin/nsenter --mount=/root/mount_namespaces/NS_NAME
 
@@ -72,13 +61,9 @@ files, so the mount namespace won't be needed for most use cases, and I
 will update the script to that the mount namespace not created unless a
 flag is passed in. Patch welcome to add that flag before then.
 
-This script has a dependency which you can download manually or it
-will be automatically downloaded into the same directory.
-It handles errors by printing stack trace and and cleaning up the namespaces.
-To download manually,
-git clone https://iankelling.org/git/errhandle
-into an adjacent directory, or
-export ERRHANDLE_PATH to point to the 'err' file in that repo.
+
+This script has a dependency
+https://savannah.nongnu.org/projects/bash-bear-trap/ . Search the script for "source" to see where to install or modify the  installed location.
 
 
 Background on this project (you can skip if you like):
@@ -143,7 +128,6 @@ if $install_error; then
 fi
 ####   end sanity checking ####
 
-
 v0=veth0-$nn
 v1=veth1-$nn
 ip_base=10.173
@@ -153,47 +137,36 @@ if ! $create && [[ $(readlink /proc/self/ns/net) == "$(readlink /proc/1/ns/net)"
 fi
 
 # make the default network namespace be named
+
+mkdir -p /run/netns
 target=/run/netns/default
 if [[ ! -e $target && ! -L $target ]]; then
-  mkdir -p /run/netns
-  ln -s /proc/1/ns/net $target
+  # -f to avoid a race condition with running twice
+  ln -sf /proc/1/ns/net $target
 fi
 
-
 ipd() { ip -n default "$@"; }
+
+
+# otherwise we are already in the network namespace and it's unnamed.
 if $create; then
-  # run ip in the network namespace
-  ipnn() { ip -n $nn "$@"; }
-else
-  # we are already in the network namespace and it's unnamed.
-  # run ip in the network namespace
-  ipnn() { ip "$@"; }
+  ipnnargs="-n $nn"
 fi
+# run ip in the network namespace
+ipnn() { ip $ipnnargs "$@"; }
+
 # default network namespace exec
 dexec() { ip netns exec default "$@"; }
 # mount namespace exec
 mexec() { /usr/bin/nsenter --mount=/root/mount_namespaces/$nn "$@"; }
 
 
-# background: head -n1 is defensive. Not sure if there is some weird feature
-# for 2 routes to be 0/0.
-gateway_ifs=($(ipd route list exact 0/0 | head -n1| sed -r 's/.*dev\s+(\S+).*/\1/'))
-
-if [[ ! $gateway_ifs ]]; then
-  cat >&2 <<EOF
-$0: error: failed to find gateway interface. No output from:
-ipd route list exact 0/0 | head -n1| sed -r 's/.*dev\s+(\S+).*/\1/'
-output from "ipd route list exact 0/0":
-$(ipd route list exact 0/0)
-EOF
-  exit 1
-fi
-
 nat() {
-  for if in ${gateway_ifs[@]}; do
-    dexec iptables -t nat $1 POSTROUTING -o $if -j MASQUERADE \
-          -m comment --comment "systemd network namespace nat"
-  done
+  # note, in a previous commit i specified the output interface with -o,
+  # but that broke things when my gateway interface changed, and I can't
+  # see any advantage to it, so I removed it.
+  dexec iptables -t nat $1 POSTROUTING -s $network.0/24 -j MASQUERADE \
+        -m comment --comment "systemd network namespace nat"
 }
 
 # d = default
@@ -267,14 +240,14 @@ start() {
     ip -n $nn link set dev lo up
   fi
 
-  echo 1 | dexec dd of=/proc/sys/net/ipv4/ip_forward 2>/dev/null
+  echo 1 | dexec dd of=/proc/sys/net/ipv4/ip_forward status=none
 
   # docker helpfully changes the default FORWARD to drop...
   diptables-add FORWARD -i $v0 -j ACCEPT
   diptables-add FORWARD -o $v0 -j ACCEPT
 
 
-  _errcatch_cleanup=stop
+  err-cleanup() { stop; }
   ipnn link add $v0 type veth peer name $v1
   ipnn link set $v0 netns default
   ipd addr add $network.1/24 dev $v0
@@ -285,7 +258,7 @@ start() {
   ipnn route add default via $network.1
 
   ###### begin setup resolvconf
-  if [[ -e /run/resolvconf ]]; then # resolvconf probably not installed
+  if [[ -e /run/resolvconf ]]; then # resolvconf probably installed
     resolv_copy=/root/resolvconf-$nn
 
     # this condition should never happen, just coding defensively