general improvements
[automated-distro-installer] / fai / config / distro-install-common / ethusb-static
index f6cdd62f959a5e383e75d841952a368402ad6c9b..0a6d1ae9a85e15af9d06d2008079eb829a44824e 100755 (executable)
@@ -30,27 +30,143 @@ shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
 set -eE -o pipefail
 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
-[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
-
 m() { printf "%s\n" "$*";  "$@"; }
 
+
+set-dynamic() {
+
+  reup=false
+  if [[ $cur_state == activated ]]; then
+    reup=true
+  fi
+
+  if [[ $cur_method != auto ]]; then
+    args+=(ipv4.method auto)
+  fi
+  if [[ $cur_ip != -- ]]; then
+    args+=(-ipv4.addresses "$ipv4_addresses")
+  fi
+  if [[ $cur_dns != -- ]]; then
+    args+=(-ipv4.dns "$ipv4_dns")
+  fi
+  if [[ $cur_gateway != -- ]]; then
+    # undocumented in t11 man nmcli. guessed randomly
+    args+=(ipv4.gateway 0.0.0.0)
+  fi
+  if (( ${#args[@]} >= 1 )); then
+    m nmcli con mod "$nm_con" "${args[@]}"
+    if $reup; then
+      m nmcli con up "$nm_con"
+    fi
+  else
+    echo "$0: found expected state, nothing to do."
+  fi
+  exit 0
+  set-nm
+}
+
+detect-net() {
+
+  # this assumes we have wifi up
+  if [[ $(timeout 1 dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \
+       && ip n show 10.2.0.1 | grep . &>/dev/null; then
+    net=home
+  elif ip r show default | grep 'via 10.0.3.1 dev wlan0' &>/dev/null && [[ $(timeout 1 dig +short @10.0.3.1 -x 10.0.3.1) == cmc1.lan. ]]; then
+    net=work
+  else
+    echo "$0: error could not detect network"
+    exit 1
+  fi
+
+}
+
+set-nm() {
+  m nmcli con mod "$nm_con" ipv4.method manual ipv4.addresses $ip ipv4.gateway $gateway ipv4.dns $dns
+  state=$(nmcli con show "$nm_con" 2>/dev/null | awk '$1 == "GENERAL.STATE:" {print $2}')
+  if [[ $state == activated ]]; then
+    m nmcli con up "$nm_con"
+  fi
+
+}
+
+get-ip() {
+
+  case $net in
+    home)
+
+      while read -r ip_suf host mac; do
+        if [[ ! $ip_suf || $ip_suf == \#* ]]; then
+          continue
+        fi
+        if [[ $mac != usb ]]; then
+          continue
+        fi
+        if [[ $host == ${HOSTNAME}c ]]; then
+
+          ip=10.2.0.$ip_suf/16
+          gateway=10.2.0.1
+          dns=8.8.8.4,8.8.8.8
+          break
+        fi
+      done </p/c/host-info
+
+      if [[ ! $ip_suf ]]; then
+        echo "$0: error: failed to find ${HOSTNAME}c ip suffix in /p/c/host-info"
+        exit 1
+      fi
+      ;;
+    work)
+
+      if ! ip r show default | grep 'via 192.168.0.1 dev eth' &>/dev/null; then
+        if [[ $cur_method != manual ]]; then
+          echo "$0: error. Need to be on wired network to get our ip"
+          exit 1
+        fi
+        set-dynamic
+        sleep 10
+      fi
+      myip=$(timeout 1 dig +short @192.168.0.25 $HOSTNAME.office.fsf.org)
+      if [[ ! $myip ]]; then
+        echo "$0: error: didnt detect home network and failed to get office ip"
+        exit 1
+      fi
+      dns=192.168.0.10,192.168.0.25
+      gateway=192.168.0.1
+      ip=$myip/24
+
+      ;;
+  esac
+}
+
+
+get-cur-val() {
+  local key
+  key=$1
+  printf "%s\n" "$tmpstr" | awk '$1 == "'$key':" {print $2}'
+}
+
+get-cur() {
+  tmpstr=$(nmcli con show "$nm_con" 2>/dev/null)
+
+  cur_method=$(get-cur-val ipv4.method)
+  cur_ip=$(get-cur-val ipv4.addresses)
+  cur_gateway=$(get-cur-val ipv4.gateway)
+  cur_dns=$(get-cur-val ipv4.dns)
+  cur_state=$(get-cur-val GENERAL.STATE)
+}
+
+
 ## begin arg parsing ##
 
 force=false
-conf_only=false
-comment='# iank file id: ethusb-dhcp-v1'
 off=false
 while [[ $1 ]]; do
   case $1 in
-    -c)
-      conf_only=true
-      ;;
     -f)
       force=true
       ;;
     off)
       off=true
-      comment='# iank file id: ethusb-static-v1'
       ;;
     *)
       echo "$0: error unexpected argument: $1" >&2
@@ -62,84 +178,92 @@ done
 
 ## end arg parsing ##
 
-
+## begin common setup / detection ##
 shopt -s nullglob
 
-# we already configured the interface once, afterwards, comment and
-# uncomment to enable/disable. This makes it so we don't depend on /p
-# being mounted.
+wiredx=1
+declare -a args
 
-conf=/etc/NetworkManager/system-connections/ethusb-static.nmconnection
-if ! $force && [[ -s $conf ]] && grep -qFx "$comment" $conf; then
-  # we already ran successfully in the past to set things this way, so
-  # do nothing.
-  exit 0
+# device that has an eth0, but we aren't using it because it is
+# broken. We could just hardcode a mac comparison with `cat
+# /sys/class/net/eth0/address` but this is cooler.
+if [[ -e  /sys/class/net/eth0 ]]; then
+  bus_info=$(ethtool -i eth0 | awk '$1 == "bus-info:" { print $2 }')
+  if [[ $bus_info != usb* ]]; then
+    wiredx=2
+  fi
 fi
 
+eth_dev=eth$(( wiredx - 1 ))
 
-if [[ $(dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \
-     && ip n show 10.2.0.1 | grep . &>/dev/null; then
-  #  we are at_home=true
+nm_con=$(nmcli device show $eth_dev | \
+           awk '$1 == "GENERAL.CONNECTION:" {out=$2; for(i=3;i<=NF;i++){out=out" "$i}; print out}' ||:)
 
-  while read -r ip_suf host mac; do
-    if [[ $mac != usb ]]; then
-      continue
-    fi
-    if [[ $host == ${HOSTNAME}c ]]; then
+if [[ ! $nm_con || $nm_con == -- ]]; then
+  nm_con="Wired connection $wiredx"
+fi
 
-      net_info="address1=10.2.0.$ip_suf/16,10.2.0.1
-dns=8.8.8.4;8.8.8.8;"
+if ! nmcli con | grep -q "^$nm_con " &>/dev/null; then
+  # Note: we could support creation through a file or via
+  # nmcli, but right now I'm ok with just having plugged in a device once
+  # since this os was installed.
+  echo "error: no existing connection: $nm_con found in output of nmcli con"
+  exit 0
+fi
 
-      break
-    fi
-  done </p/c/host-info
 
-  if [[ ! $ip_suf ]]; then
-    echo "$0: error: failed to find ${HOSTNAME}c ip suffix in /p/c/host-info"
-    exit 1
-  fi
-else
-  ip=$(getent ahostsv4 $HOSTNAME.office.fsf.org | awk '{ print $1 }' | head -n1)
-  net_info="address1=$ip/24,192.168.0.1
-dns=192.168.0.10;192.168.0.25;"
+if ! type -p dig &>/dev/null; then
+  apt-get install dig
 fi
 
-wiredx=
+get-cur
+## end common setup / detection ##
 
-# device that has an eth0, but we aren't using it because it is
-# broken. We could just hardcode a mac comparison with `cat
-# /sys/class/net/eth0/address` but this is cooler.
-if [[ -e  /sys/class/net/eth0 ]]; then
-  bus_info=$(ethtool -i eth0 | awk '$1 == "bus-info:" { print $2 }')
-  if [[ $bus_info != usb* ]]; then
-    wiredx=2
-  fi
+if $off; then
+  set-dynamic
+  exit 0
 fi
 
-ethx=$(( wiredx - 1 ))
+detect-net
+get-ip
 
+if ! $force && [[ "$cur_method $cur_gateway $cur_dns $cur_ip" == "manual $gateway $dns $ip" ]]; then
+  echo "$0: found expected state, nothing to do."
+  exit 0
+fi
 
+set-nm
 
-uuid=$(nmcli con show "Wired connection $wiredx" 2>/dev/null | awk '$1 == "connection.uuid:" {print $2}' ||:)
-if [[ ! $uuid ]]; then
-  # just a uuid that nm generated for me at some point
-  uuid=0da4c614-6a3c-3ad2-8d4b-c6eebe0814c3
-fi
 
 
-# This template is the result of running, for example
+# example of down cli
+#nmcli con mod 'Wired connection 1' ipv4.method auto -ipv4.addresses 10.2.0.9/16 ipv4.gateway 0.0.0.0 -ipv4.dns "8.8.8.4,8.8.8.8"
+
+
+# FYI: the result of running, for example
 # nmcli con mod "Wired connection 1" \
+  #         ipv4.method manual \
   #       ipv4.addresses "10.2.0.23/24" \
   #       ipv4.gateway "10.2.0.1" \
   #       ipv4.dns "8.8.8.4,8.8.8.8"
 
-# which creates a fille named "Wired connection 1.nmconnection",
-# below. I see no reason to keep the same file name, or a bunch of
+# creates a fille named "/etc/NetworkManager/system-connections/Wired connection 1.nmconnection",
+# below.
+#
+# The nmcli man page says you should just edit files in that dir and
+# then run nmcli con reload to reread them all to load your changes, but
+# I've found that to be unreliable, the systemd journal would say
+# something like "reload happened" then nothing would change in the
+# connect that the file clearly modifies, so I switched over to using
+# the command line and just ignoring those files.
+#
+# I see no reason to keep the same file name, or a bunch of
 # setting that seem irrelevant, and empty sections don't seem to do
 # anything according to the man page.
+#
 
 # [connection]
-# id=Wired connection 2
+# id=Wired connection 1
 # uuid=b0fb7694-dfe6-31a1-81fa-7c17b61515a7
 # type=ethernet
 # interface-name=eth1
@@ -157,45 +281,3 @@ fi
 # method=auto
 
 # [proxy]
-
-{
-  cat <<EOF
-[connection]
-id=Wired connection $wiredx
-uuid=$uuid
-type=ethernet
-interface-name=eth$ethx
-
-[ipv4]
-EOF
-  if $off; then
-    cat <<'EOF'
-method=auto
-EOF
-  else
-    cat <<EOF
-$net_info
-method=manual
-EOF
-  fi
-} | install -T -m0600 /dev/stdin $conf
-
-if ! $conf_only; then
-  state=$(nmcli con show $uuid 2>/dev/null | awk '$1 == "GENERAL.STATE:" {print $2}' ||:)
-
-  reup=false
-  if [[ $state == activated ]]; then
-    reup=true
-  fi
-
-  m nmcli con reload
-
-  if $reup; then
-    m nmcli con down $uuid
-    m nmcli con up $uuid
-  fi
-fi
-
-if ! grep -F "$comment" $conf; then
-  printf "%s\n" "$comment" >>$conf
-fi