bug fix
[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 [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
34
35 m() { printf "%s\n" "$*"; "$@"; }
36
37 ## begin arg parsing ##
38
39 force=false
40 conf_only=false
41 comment='# iank file id: ethusb-dhcp-v1'
42 off=false
43 while [[ $1 ]]; do
44 case $1 in
45 -c)
46 conf_only=true
47 ;;
48 -f)
49 force=true
50 ;;
51 off)
52 off=true
53 comment='# iank file id: ethusb-static-v1'
54 ;;
55 *)
56 echo "$0: error unexpected argument: $1" >&2
57 exit 1
58 ;;
59 esac
60 shift
61 done
62
63 ## end arg parsing ##
64
65
66 shopt -s nullglob
67
68 # we already configured the interface once, afterwards, comment and
69 # uncomment to enable/disable. This makes it so we don't depend on /p
70 # being mounted.
71
72 conf=/etc/NetworkManager/system-connections/ethusb-static.nmconnection
73 if ! $force && [[ -s $conf ]] && grep -qFx "$comment" $conf; then
74 # we already ran successfully in the past to set things this way, so
75 # do nothing.
76 exit 0
77 fi
78
79
80 if [[ $(dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \
81 && ip n show 10.2.0.1 | grep . &>/dev/null; then
82 # we are at_home=true
83
84 while read -r ip_suf host mac; do
85 if [[ $mac != usb ]]; then
86 continue
87 fi
88 if [[ $host == ${HOSTNAME}c ]]; then
89
90 net_info="address1=10.2.0.$ip_suf/16,10.2.0.1
91 dns=8.8.8.4;8.8.8.8;"
92
93 break
94 fi
95 done </p/c/host-info
96
97 if [[ ! $ip_suf ]]; then
98 echo "$0: error: failed to find ${HOSTNAME}c ip suffix in /p/c/host-info"
99 exit 1
100 fi
101 else
102 if ! type -p dig &>/dev/null; then
103 apt-get install dig
104 fi
105 ip=$(dig +short @192.168.0.25 $HOSTNAME.office.fsf.org)
106 net_info="address1=$ip/24,192.168.0.1
107 dns=192.168.0.10;192.168.0.25;"
108 fi
109
110 wiredx=
111
112 # device that has an eth0, but we aren't using it because it is
113 # broken. We could just hardcode a mac comparison with `cat
114 # /sys/class/net/eth0/address` but this is cooler.
115 if [[ -e /sys/class/net/eth0 ]]; then
116 bus_info=$(ethtool -i eth0 | awk '$1 == "bus-info:" { print $2 }')
117 if [[ $bus_info != usb* ]]; then
118 wiredx=2
119 fi
120 fi
121
122 ethx=$(( wiredx - 1 ))
123
124
125
126 uuid=$(nmcli con show "Wired connection $wiredx" 2>/dev/null | awk '$1 == "connection.uuid:" {print $2}' ||:)
127 if [[ ! $uuid ]]; then
128 # just a uuid that nm generated for me at some point
129 uuid=0da4c614-6a3c-3ad2-8d4b-c6eebe0814c3
130 fi
131
132
133 # This template is the result of running, for example
134 # nmcli con mod "Wired connection 1" \
135 # ipv4.addresses "10.2.0.23/24" \
136 # ipv4.gateway "10.2.0.1" \
137 # ipv4.dns "8.8.8.4,8.8.8.8"
138
139 # which creates a fille named "Wired connection 1.nmconnection",
140 # below. I see no reason to keep the same file name, or a bunch of
141 # setting that seem irrelevant, and empty sections don't seem to do
142 # anything according to the man page.
143
144 # [connection]
145 # id=Wired connection 2
146 # uuid=b0fb7694-dfe6-31a1-81fa-7c17b61515a7
147 # type=ethernet
148 # interface-name=eth1
149 # timestamp=1715728264
150
151 # [ethernet]
152
153 # [ipv4]
154 # address1=10.2.0.23/16,10.2.0.1
155 # dns=8.8.8.4;8.8.8.8;
156 # method=manual
157
158 # [ipv6]
159 # addr-gen-mode=stable-privacy
160 # method=auto
161
162 # [proxy]
163
164 {
165 cat <<EOF
166 [connection]
167 id=Wired connection $wiredx
168 uuid=$uuid
169 type=ethernet
170 interface-name=eth$ethx
171
172 [ipv4]
173 EOF
174 if $off; then
175 cat <<'EOF'
176 method=auto
177 EOF
178 else
179 cat <<EOF
180 $net_info
181 method=manual
182 EOF
183 fi
184 } | install -T -m0600 /dev/stdin $conf
185
186 if ! $conf_only; then
187 state=$(nmcli con show $uuid 2>/dev/null | awk '$1 == "GENERAL.STATE:" {print $2}' ||:)
188
189 reup=false
190 if [[ $state == activated ]]; then
191 reup=true
192 fi
193
194 m nmcli con reload
195
196 if $reup; then
197 m nmcli con down $uuid
198 m nmcli con up $uuid
199 fi
200 fi
201
202 if ! grep -F "$comment" $conf; then
203 printf "%s\n" "$comment" >>$conf
204 fi