Merge ~smoser/ubuntu/+source/initramfs-tools:bug/1714308-initramfs-dns into ubuntu/+source/initramfs-tools:ubuntu/devel

Proposed by Scott Moser
Status: Merged
Merged at revision: b3b99af80346ef1dfc90eb7150492d1fc2936ef8
Proposed branch: ~smoser/ubuntu/+source/initramfs-tools:bug/1714308-initramfs-dns
Merge into: ubuntu/+source/initramfs-tools:ubuntu/devel
Diff against target: 323 lines (+238/-5)
7 files modified
debian/changelog (+7/-0)
scripts/functions (+183/-5)
tests/test_netinfo.d/ipv4/netplan/eth1.yaml (+9/-0)
tests/test_netinfo.d/ipv4and6/netplan/eth0.yaml (+10/-0)
tests/test_netinfo.d/ipv4static/netplan/eth1.yaml (+6/-0)
tests/test_netinfo.d/ipv6/netplan/eno1.yaml (+8/-0)
tests/test_netinfo.sh (+15/-0)
Reviewer Review Type Date Requested Status
Mathieu Trudel-Lapierre (community) Needs Fixing
git-ubuntu developers Pending
Review via email: mp+341203@code.launchpad.net
To post a comment you must log in.
25228cf... by Scott Moser

add 'dhcp-identifier: mac' to netplan dhcp stanzas

dfc5290... by Scott Moser

clean up implementation of only declaring macaddress= once.

Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

This won't be sufficient, looks like it's missing at least the rest of the yaml:

network:
  version: 2
  ethernets:

[etc.]

Even fudging this together for now, restarting systemd-networkd leads to the system hanging.

review: Needs Fixing
Revision history for this message
Scott Moser (smoser) wrote :

> This won't be sufficient, looks like it's missing at least the rest of the
> yaml:
>
> network:
> version: 2
> ethernets:

I'll add this.

>
> [etc.]
>
> Even fudging this together for now, restarting systemd-networkd leads to the
> system hanging.

Well, why would you *restart* systemd-networkd ? these are written in the initramfs systemd-networkd would not have been started yet.

b692527... by Scott Moser

add 'network/ethernets/' header stanza to each netplan rendered config.

2 things:
a.) add the network/ethernets namespace to the rendered yaml files.
b.) render addresses as a single line list.

Revision history for this message
Scott Moser (smoser) wrote :

updated to write network/config header.

Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

This won't work as-is; we'll need 'critical: yes' also under dhcp / dhcp-identifer. I'm preparing the SRU for this.

Currently, the behavior for systemd appears to be to release IP addresses when it reloads... :(

review: Needs Fixing
Revision history for this message
Scott Moser (smoser) wrote :

"Under" ?

Can you give an example?

It doesn't seem to make sense for 'critical' to apply at the same level of 'dhcp6' or 'dhcp4', as it is possible that one is critical and one is not.

Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

This has been merged already; NFS appears to work quite well now (no hang when running 'netplan apply'). Thanks!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 2f34bfa..eadc51b 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,10 @@
6+initramfs-tools (0.130ubuntu4) UNRELEASED; urgency=medium
7+
8+ * scripts/functions: write netplan config files to /run/netplan for
9+ network devices configured with configure_networking. (LP: #1713803)
10+
11+ -- Scott Moser <smoser@brickies.net> Fri, 09 Mar 2018 09:23:46 +0100
12+
13 initramfs-tools (0.130ubuntu3) bionic; urgency=medium
14
15 * Fix resuming a hibernate session from a swapfile (LP: #1644975)
16diff --git a/scripts/functions b/scripts/functions
17index e5e1029..72d5b48 100644
18--- a/scripts/functions
19+++ b/scripts/functions
20@@ -388,6 +388,8 @@ configure_networking()
21
22 netinfo_to_resolv_conf /etc/resolv.conf \
23 /run/net-${DEVICE}.conf /run/net-*.conf /run/net6-*.conf
24+ netinfo_to_netplan /run/netplan \
25+ /run/net-${DEVICE}.conf /run/net-*.conf /run/net6-*.conf
26 }
27
28 netinfo_to_resolv_conf() {
29@@ -398,10 +400,8 @@ netinfo_to_resolv_conf() {
30 ( _in_subshell=1; netinfo_to_resolv_conf "$@" )
31 return
32 fi
33-
34 local output="$1" search="" ns="" f="" n=""
35 shift
36- {
37 for f in "$@"; do
38 [ -f "$f" ] || continue
39 unset IPV4DNS0 IPV4DNS1 IPV6DNS0 IPV6DNS1
40@@ -427,13 +427,191 @@ netinfo_to_resolv_conf() {
41 search=${search# }
42 ns=${ns# }
43 done
44+
45+ local rconf="" CR="
46+"
47 for n in ${ns}; do
48- echo "nameserver $n"
49+ rconf="${rconf}nameserver $n${CR}"
50 done
51 if [ -n "${search}" ]; then
52- echo "search ${search}"
53+ rconf="${rconf}search ${search}${CR}"
54+ fi
55+ if [ -z "$rconf" ]; then
56+ echo "no search or nameservers found in $*" 1>&2
57+ fi
58+ if [ "$rconf" = "-" ]; then
59+ echo -n "$rconf"
60+ else
61+ echo -n "$rconf" > "$output"
62+ fi
63+}
64+
65+mask2cidr() {
66+ # https://forum.openwrt.org/viewtopic.php?pid=220781#p220781
67+ # Assumes there's no "255." after a non-255 byte in the mask
68+ local x=${1##*255.}
69+ set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
70+ x=${1%%$3*}
71+ echo $(( $2 + (${#x}/4) ))
72+}
73+
74+_declare_sh_append_var() {
75+ # append_var(name, skip, strings)
76+ # write a declaration of name that will append to any existing
77+ local name="$1" skip="$2" add="" n=""
78+ shift 2
79+ for n in "$@"; do
80+ [ -n "$n" -a "$n" != "$skip" ] || continue
81+ add="$add $n"
82+ done
83+ add=${add# }
84+ [ -n "$add" ] || return 0
85+ echo "$name=\"\${${name}:+\${${name}} }${add}\""
86+}
87+
88+_declare_ip_info() {
89+ # declare_ip_info(version, proto, address, netmask, gateway)
90+ local version="$1" proto="$2" address="$3" netmask="$4" gateway="$5"
91+ local netprefix=""
92+ if [ "$proto" = "dhcp" -o "$proto" = "dhcp4" -o "$proto" = "dhcp6" ]; then
93+ echo "dhcp${version}=true"
94+ elif [ "$proto" = "static" ]; then
95+ if [ -n "$address" ]; then
96+ netprefix=$netmask
97+ if [ "$version" = "4" ]; then
98+ netprefix=$(mask2cidr "$netmask")
99+ fi
100+ _declare_sh_append_var addresses "" "$address/$netprefix"
101+ fi
102+ if [ -n "$gateway" ]; then
103+ echo "gateway${version}=$gateway"
104+ fi
105+ fi
106+}
107+
108+_render_netplan() {
109+ # write a netplan stanza for the given device.
110+ local name="$1" mac="$2" dhcp4="$3" dhcp6="$4" addrs="$5" \
111+ gateway4="$6" gateway6="$7" ns_addrs="$8" ns_search="$9"
112+ local n found="" bi=" " alist="" slist=""
113+ echo "network:"
114+ echo " version: 2"
115+ echo " ethernets:"
116+ echo " $name:"
117+ if [ -n "$mac" ]; then
118+ echo "$bi match:"
119+ echo "$bi macaddress: \"$mac\""
120+ echo "$bi set-name: $name"
121+ fi
122+ if [ -n "$dhcp4" ]; then
123+ echo "$bi dhcp4: $dhcp4"
124+ echo "$bi dhcp-identifier: mac"
125 fi
126- } > "$output"
127+ [ -n "$dhcp6" ] && echo "$bi dhcp6: $dhcp6"
128+ if [ -n "$addrs" ]; then
129+ alist=""
130+ found=","
131+ for n in $addrs; do
132+ # remove dups
133+ [ "${found#*,$n,}" = "${found}" ] || continue
134+ found="${found}$n,"
135+ alist="${alist}\"$n\", "
136+ done
137+ echo "$bi addresses: [${alist%, }]"
138+ fi
139+ [ -n "$gateway4" ] && echo "$bi gateway4: \"$gateway4\""
140+ [ -n "$gateway6" ] && echo "$bi gateway6: \"$gateway6\""
141+
142+ if [ -n "$ns_addrs" ]; then
143+ alist="["
144+ for n in $ns_addrs; do
145+ # do not put in duplicates
146+ [ "${alist#*\"$n\"}" = "$alist" ] || continue
147+ alist="${alist}\"$n\", ";
148+ done
149+ alist="${alist%, }]"
150+
151+ if [ -n "$ns_search" ]; then
152+ slist="["
153+ for n in ${ns_search}; do
154+ # do not put in duplicates
155+ [ "${slist#*\"$n\"}" = "$slist" ] || continue
156+ slist="${slist}\"$n\", ";
157+ done
158+ slist="${slist%, }]"
159+ fi
160+ echo "$bi nameservers:"
161+ echo "$bi addresses: $alist"
162+ [ -n "$slist" ] && echo "$bi search: $slist"
163+ fi
164+}
165+
166+netinfo_to_netplan() {
167+ # read /run/net-* files write netplan config.
168+ if [ "${_in_subshell:-0}" = "0" ]; then
169+ # subshell to avoid modification of variables by '.'
170+ ( _in_subshell=1; netinfo_to_netplan "$@" )
171+ return
172+ fi
173+ local out_d="$1" tmpd
174+ if command -v mktemp >/dev/null 2>&1; then
175+ tmpd=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX")
176+ else
177+ tmpd="${TMPDIR:-/tmp}/${0##*/}.niinfo.$$"
178+ mkdir -p "$tmpd" || return
179+ fi
180+
181+ local devices="" pre="" mac="" first=""
182+ # we go through all the files presented and create per-device files in
183+ # a tmpdir that are shell sourceable and closer to the netplan that
184+ # we want to render. Then render those to netplan stanzas.
185+ for f in "$@"; do
186+ [ -f "$f" ] || continue
187+ unset DEVICE DEVICE6 PROTO IPV6PROTO
188+ unset IPV6ADDR IPV6NETMASK IPV6GATEWAY
189+ unset IPV4ADDR IPV4NETMASK IPV4GATEWAY
190+ . "$f" || { echo "WARN: failed '. \"$f\"'" 1>&2; return 1; }
191+ local name=""
192+ name=${DEVICE:-${DEVICE6}}
193+ [ -n "$name" ] || {
194+ echo "WARN: $f did not define DEVICE or DEVICE6" 1>&2;
195+ return 1;
196+ }
197+ case " ${devices} " in
198+ *\ ${name}\ *) first=false;;
199+ *) first=true; devices="${devices} ${name}";;
200+ esac
201+
202+ {
203+ if [ "$first" = "true" -a -r "/sys/class/net/$name/address" ]; then
204+ read mac < /sys/class/net/$name/address &&
205+ echo "macaddress=$mac" ||
206+ echo "WARN: failed to read mac for $name" 1>&2
207+ fi
208+ if [ -n "$DEVICE" ]; then
209+ _declare_ip_info 4 "$PROTO" "$IPV4ADDR" "$IPV4NETMASK" "$IPV4GATEWAY"
210+ elif [ -n "$DEVICE6" ]; then
211+ _declare_ip_info 6 "$IPV6PROTO" "$IPV6ADDR" "$IPV6NETMASK" \
212+ "$IPV6GATEWAY"
213+ fi
214+ _declare_sh_append_var ns_addresses "0.0.0.0" \
215+ "${IPV4DNS0}" "${IPV4DNS1}" "${IPV6DNS0}" "${IPV6DNS1}"
216+ _declare_sh_append_var ns_search "" "$DOMAINSEARCH" "$IPV6DOMAINSEARCH"
217+ } >> "$tmpd/$name"
218+ done
219+
220+ [ -d "$out_d" ] || mkdir -p "$out_d" ||
221+ { echo "WARN: failed mkdir $out_d"; return 1; }
222+
223+ for name in $devices; do
224+ local macaddress="" dhcp4="" dhcp6="" addresses=""
225+ local gateway4="" gateway6="" ns_addresses="" ns_search=""
226+ . "$tmpd/$name"
227+ _render_netplan "$name" "$macaddress" "$dhcp4" "$dhcp6" "$addresses" \
228+ "$gateway4" "$gateway6" "$ns_addresses" "$ns_search" \
229+ > "${out_d}/$name.yaml"
230+ done
231+ rm -Rf "$tmpd"
232 }
233
234 # Wait for queued kernel/udev events
235diff --git a/tests/test_netinfo.d/ipv4/netplan/eth1.yaml b/tests/test_netinfo.d/ipv4/netplan/eth1.yaml
236new file mode 100644
237index 0000000..96770c6
238--- /dev/null
239+++ b/tests/test_netinfo.d/ipv4/netplan/eth1.yaml
240@@ -0,0 +1,9 @@
241+network:
242+ version: 2
243+ ethernets:
244+ eth1:
245+ dhcp4: true
246+ dhcp-identifier: mac
247+ nameservers:
248+ addresses: ["192.168.122.1"]
249+ search: ["foo.com"]
250diff --git a/tests/test_netinfo.d/ipv4and6/netplan/eth0.yaml b/tests/test_netinfo.d/ipv4and6/netplan/eth0.yaml
251new file mode 100644
252index 0000000..b7433c5
253--- /dev/null
254+++ b/tests/test_netinfo.d/ipv4and6/netplan/eth0.yaml
255@@ -0,0 +1,10 @@
256+network:
257+ version: 2
258+ ethernets:
259+ eth0:
260+ dhcp4: true
261+ dhcp-identifier: mac
262+ dhcp6: true
263+ nameservers:
264+ addresses: ["192.168.122.1", "2001:67c:1562:8010::2:1"]
265+ search: ["foo.com", "example.com", "ubuntu.com"]
266diff --git a/tests/test_netinfo.d/ipv4static/netplan/eth1.yaml b/tests/test_netinfo.d/ipv4static/netplan/eth1.yaml
267new file mode 100644
268index 0000000..4fea0e5
269--- /dev/null
270+++ b/tests/test_netinfo.d/ipv4static/netplan/eth1.yaml
271@@ -0,0 +1,6 @@
272+network:
273+ version: 2
274+ ethernets:
275+ eth1:
276+ addresses: ["10.0.0.2/24"]
277+ gateway4: "10.0.0.1"
278diff --git a/tests/test_netinfo.d/ipv6/netplan/eno1.yaml b/tests/test_netinfo.d/ipv6/netplan/eno1.yaml
279new file mode 100644
280index 0000000..631d62b
281--- /dev/null
282+++ b/tests/test_netinfo.d/ipv6/netplan/eno1.yaml
283@@ -0,0 +1,8 @@
284+network:
285+ version: 2
286+ ethernets:
287+ eno1:
288+ dhcp6: true
289+ nameservers:
290+ addresses: ["2001:67c:1562:8010::2:1"]
291+ search: ["example.com", "ubuntu.com"]
292diff --git a/tests/test_netinfo.sh b/tests/test_netinfo.sh
293index bd92173..2ebc554 100755
294--- a/tests/test_netinfo.sh
295+++ b/tests/test_netinfo.sh
296@@ -52,6 +52,18 @@ run_resolvconf() {
297 pass_on_nodiff "$tname" "$expected" "$found"
298 }
299
300+run_netinfo_to_netplan() {
301+ local bname="$1" testdir="$2" results_d="$3"
302+ local tname="$bname-netinfo-to-netplan"
303+ shift 3
304+ local found_d="$results_d/netplan"
305+ local expected_d="$testdir/netplan"
306+ [ -d "$expected_d" ] || return $RET_SKIP
307+
308+ _run_in_functions "$tname" netinfo_to_netplan "$found_d" "$@" || return
309+ pass_on_nodiff "$tname" "$expected_d" "$found_d"
310+}
311+
312 record() {
313 local ret="$1"
314 case "$ret" in
315@@ -73,6 +85,9 @@ for testdir in "${data_dir}"/*; do
316 run_resolvconf "$dname" "$testdir" "$results_d" $confs
317 record $?
318
319+ run_netinfo_to_netplan "$dname" "$testdir" "$results_d" $confs
320+ record $?
321+
322 rm -Rf "${results_d}"
323 done
324

Subscribers

People subscribed via source and target branches