various fixes, improvements, shellcheck
[automated-distro-installer] / fai / config / distro-install-common / ethusb-static
diff --git a/fai/config/distro-install-common/ethusb-static b/fai/config/distro-install-common/ethusb-static
new file mode 100755 (executable)
index 0000000..f6cdd62
--- /dev/null
@@ -0,0 +1,201 @@
+#!/bin/bash
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# usage $0 [-c] [off]
+# off:   Turn off static ip.
+# -c    config only, don't tell networkmanager to change anything
+# -f    force interface reup
+
+if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
+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" "$*";  "$@"; }
+
+## 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
+      exit 1
+      ;;
+  esac
+  shift
+done
+
+## end arg parsing ##
+
+
+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.
+
+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
+fi
+
+
+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
+
+  while read -r ip_suf host mac; do
+    if [[ $mac != usb ]]; then
+      continue
+    fi
+    if [[ $host == ${HOSTNAME}c ]]; then
+
+      net_info="address1=10.2.0.$ip_suf/16,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
+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;"
+fi
+
+wiredx=
+
+# 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
+
+ethx=$(( wiredx - 1 ))
+
+
+
+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
+# nmcli con mod "Wired connection 1" \
+  #       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
+# setting that seem irrelevant, and empty sections don't seem to do
+# anything according to the man page.
+
+# [connection]
+# id=Wired connection 2
+# uuid=b0fb7694-dfe6-31a1-81fa-7c17b61515a7
+# type=ethernet
+# interface-name=eth1
+# timestamp=1715728264
+
+# [ethernet]
+
+# [ipv4]
+# address1=10.2.0.23/16,10.2.0.1
+# dns=8.8.8.4;8.8.8.8;
+# method=manual
+
+# [ipv6]
+# addr-gen-mode=stable-privacy
+# 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