fixes, minor config change
[automated-distro-installer] / fai / config / distro-install-common / ethusb-static
1 #!/bin/bash
2 # I, Ian Kelling, follow the GNU license recommendations at
3 # https://www.gnu.org/licenses/license-recommendations.en.html. They
4 # recommend that small programs, < 300 lines, be licensed under the
5 # Apache License 2.0. This file contains or is part of one or more small
6 # programs. If a small program grows beyond 300 lines, I plan to switch
7 # its license to GPL.
8
9 # Copyright 2024 Ian Kelling
10
11 # Licensed under the Apache License, Version 2.0 (the "License");
12 # you may not use this file except in compliance with the License.
13 # You may obtain a copy of the License at
14
15 # http://www.apache.org/licenses/LICENSE-2.0
16
17 # Unless required by applicable law or agreed to in writing, software
18 # distributed under the License is distributed on an "AS IS" BASIS,
19 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 # See the License for the specific language governing permissions and
21 # limitations under the License.
22
23 # usage $0 [-c] [off]
24 # off: Turn off static ip.
25 # -c config only, don't tell networkmanager to change anything
26 # -f force interface reup
27
28 if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
29 shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
30 set -eE -o pipefail
31 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
32
33 m() { printf "%s\n" "$*"; "$@"; }
34
35 ## begin arg parsing ##
36
37 force=false
38 off=false
39 while [[ $1 ]]; do
40 case $1 in
41 -f)
42 force=true
43 ;;
44 off)
45 off=true
46 ;;
47 *)
48 echo "$0: error unexpected argument: $1" >&2
49 exit 1
50 ;;
51 esac
52 shift
53 done
54
55 ## end arg parsing ##
56
57
58 shopt -s nullglob
59
60 wiredx=1
61
62 # device that has an eth0, but we aren't using it because it is
63 # broken. We could just hardcode a mac comparison with `cat
64 # /sys/class/net/eth0/address` but this is cooler.
65 if [[ -e /sys/class/net/eth0 ]]; then
66 bus_info=$(ethtool -i eth0 | awk '$1 == "bus-info:" { print $2 }')
67 if [[ $bus_info != usb* ]]; then
68 wiredx=2
69 fi
70 fi
71
72 eth_dev=eth$(( wiredx - 1 ))
73
74 nm_con=$(nmcli device show $eth_dev | \
75 awk '$1 == "GENERAL.CONNECTION:" {out=$2; for(i=3;i<=NF;i++){out=out" "$i}; print out}' ||:)
76
77 if [[ ! $nm_con ]]; then
78 nm_con="Wired connection $wiredx"
79 fi
80
81
82 con_exists=false
83 if nmcli con | grep -q "^$nm_con " &>/dev/null; then
84 con_exists=true
85 fi
86
87 declare -a args
88 if $off; then
89
90 if ! $con_exists; then
91 echo "warning: no existing connection: $nm_con found in output of nmcli con"
92 exit 0
93 fi
94
95
96 tmpstr=$(nmcli con show "$nm_con" 2>/dev/null | sort -r | awk '$1 == "ipv4.method:" || $1 == "ipv4.addresses:" || $1 == "ipv4.gateway:" || $1 == "ipv4.dns:" || $1 == "GENERAL.STATE:" {print $2}' )
97 {
98 read -r ipv4_method
99 read -r ipv4_gateway
100 read -r ipv4_dns
101 read -r ipv4_addresses
102 read -r state
103 }<<<"$tmpstr"
104
105 reup=false
106 if [[ $state == activated ]]; then
107 reup=true
108 fi
109
110 if [[ $ipv4_method != auto ]]; then
111 args+=(ipv4.method auto)
112 fi
113 if [[ $ipv4_addresses != -- ]]; then
114 args+=(-ipv4.addresses "$ipv4_addresses")
115 fi
116 if [[ $ipv4_dns != -- ]]; then
117 args+=(-ipv4.dns "$ipv4_dns")
118 fi
119 if [[ $ipv4_gateway != -- ]]; then
120 # undocumented in t11 man nmcli. guessed randomly
121 args+=(ipv4.gateway 0.0.0.0)
122 fi
123 if (( ${#args[@]} >= 1 )); then
124 m nmcli con mod "$nm_con" "${args[@]}"
125 if $reup; then
126 m nmcli con up "$nm_con"
127 fi
128 else
129 echo "$0: found expected state, nothing to do."
130 fi
131 exit 0
132 fi
133
134
135 if [[ $(dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \
136 && ip n show 10.2.0.1 | grep . &>/dev/null; then
137 # we are at_home=true
138
139 while read -r ip_suf host mac; do
140 if [[ ! $ip_suf || $ip_suf == \#* ]]; then
141 continue
142 fi
143 if [[ $mac != usb ]]; then
144 continue
145 fi
146 if [[ $host == ${HOSTNAME}c ]]; then
147
148 ip=10.2.0.$ip_suf/16
149 gateway=10.2.0.1
150 dns=8.8.8.4,8.8.8.8
151 break
152 fi
153 done </p/c/host-info
154
155 if [[ ! $ip_suf ]]; then
156 echo "$0: error: failed to find ${HOSTNAME}c ip suffix in /p/c/host-info"
157 exit 1
158 fi
159 else
160 if ! type -p dig &>/dev/null; then
161 apt-get install dig
162 fi
163 myip=$(dig +short @192.168.0.25 $HOSTNAME.office.fsf.org)
164 if [[ ! $ip ]]; then
165 echo "$0: error: didnt detect home network and failed to get office ip"
166 exit 1
167 fi
168 dns=192.168.0.10,192.168.0.25
169 gateway=192.168.0.1
170 ip=$myip/24
171 fi
172
173 if ! $force && $con_exists; then
174 current=$(nmcli con show "$nm_con" 2>/dev/null | sort -r | awk '$1 == "ipv4.method:" || $1 == "ipv4.addresses:" || $1 == "ipv4.gateway:" || $1 == "ipv4.dns:" {print $2}')
175 expected="manual
176 $gateway
177 $dns
178 $ip"
179 if [[ $current == "$expected" ]]; then
180 echo "$0: found expected state, nothing to do."
181 exit 0
182 fi
183 fi
184
185 m nmcli con mod 'Wired connection 1' ipv4.method manual ipv4.addresses $ip ipv4.gateway $gateway ipv4.dns $dns
186
187 state=$(nmcli con show "$nm_con" 2>/dev/null | awk '$1 == "GENERAL.STATE:" {print $2}')
188 if [[ $state == activated ]]; then
189 m nmcli con up "$nm_con"
190 fi
191
192
193 # example of down cli
194 #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"
195
196
197 # FYI: the result of running, for example
198 # nmcli con mod "Wired connection 1" \
199 # ipv4.method manual \
200 # ipv4.addresses "10.2.0.23/24" \
201 # ipv4.gateway "10.2.0.1" \
202 # ipv4.dns "8.8.8.4,8.8.8.8"
203
204 # creates a fille named "/etc/NetworkManager/system-connections/Wired connection 1.nmconnection",
205 # below.
206 #
207 # The nmcli man page says you should just edit files in that dir and
208 # then run nmcli con reload to reread them all to load your changes, but
209 # I've found that to be unreliable, the systemd journal would say
210 # something like "reload happened" then nothing would change in the
211 # connect that the file clearly modifies, so I switched over to using
212 # the command line and just ignoring those files.
213 #
214 # I see no reason to keep the same file name, or a bunch of
215 # setting that seem irrelevant, and empty sections don't seem to do
216 # anything according to the man page.
217 #
218
219 # [connection]
220 # id=Wired connection 1
221 # uuid=b0fb7694-dfe6-31a1-81fa-7c17b61515a7
222 # type=ethernet
223 # interface-name=eth1
224 # timestamp=1715728264
225
226 # [ethernet]
227
228 # [ipv4]
229 # address1=10.2.0.23/16,10.2.0.1
230 # dns=8.8.8.4;8.8.8.8;
231 # method=manual
232
233 # [ipv6]
234 # addr-gen-mode=stable-privacy
235 # method=auto
236
237 # [proxy]