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

Proposed by Scott Moser on 2017-08-31
Status: Needs review
Proposed branch: ~smoser/ubuntu/+source/initramfs-tools:bug/1714308-initramfs-dns
Merge into: ~usd-import-team/ubuntu/+source/initramfs-tools:ubuntu/devel
Diff against target: 301 lines (+216/-5)
7 files modified
debian/changelog (+7/-0)
scripts/functions (+174/-5)
tests/test_netinfo.d/ipv4/netplan/eth1.yaml (+5/-0)
tests/test_netinfo.d/ipv4and6/netplan/eth0.yaml (+6/-0)
tests/test_netinfo.d/ipv4static/netplan/eth1.yaml (+4/-0)
tests/test_netinfo.d/ipv6/netplan/eno1.yaml (+5/-0)
tests/test_netinfo.sh (+15/-0)
Reviewer Review Type Date Requested Status
Ubuntu Server Dev import team 2017-08-31 Pending
Review via email: mp+330043@code.launchpad.net

Description of the Change

networking: write netplan files in /run/netplan, add some tests.

Render /run/netplan/*.conf files for each device configured in the
initramfs.

The netinfo_to_netplan function handles reading 'netinfo' style files
(those written by klibcs 'ipconfig' or the dhclient for the ipv6 path)
and writing /run/netplan/<device>.conf files.

Note the following use cases that are not covered:
 a. user has files in the root /etc/netplan that conflict with the
    generated /run/netplan/*.conf files.
 b. the networking configured by 'configure_networking' was only desired
    to be used in the initramfs and not afterward.

Note also that the order of arguments passed to netinfo_to_netplan is
important and will have implications on things such as nameservers/search
keys.

Also, adds some tests for the netplan rendering.
This extends the tests/run-tests that I previously added
and puts a new tests/test_netinfo.sh and tests/test_netinfo.d.

LP: #1713803

To post a comment you must log in.
Scott Moser (smoser) wrote :

I thought some after I put this up.
I think it might make sense for the netplan path to have the initramfs write netplan configuration to /run/netplan/ (I think it reads there).

Scott Moser (smoser) wrote :

OK.
Now this branch is writing resolv.conf in the initramfs and also writing /run/netplan/<device>.yaml files.
I've added some tests to verify output.

I've not integration tested, but it seems that there is a fair shot now that
if we have this code boot with 'ip=' on the command line then it will
write /run/netplan/eth0.yaml that would then get moved from the initramfs over
to the real root.

since the /run/netplan files will have dns info in them i think that netplan might
do the right thing. The thing i'm not sure about is if netplan will bounce the
interfaces or not.

1d11695... by Scott Moser on 2017-09-05

scripts/functions: support netplan writing

aabc1e0... by Scott Moser on 2017-09-05

add netplan tests.

6b8d55b... by Scott Moser on 2017-09-05

update changelog (netplan writing)

9f473ce... by Scott Moser on 2017-09-19

Import patches-unapplied version 0.125ubuntu11 to ubuntu/artful-proposed

Imported using git-ubuntu import.

Publish parent: 48b52ea2b8d6699c5c09e01967bae4e276bc3ca9

New changelog entries:
  * hook-functions, mkinitramfs, scripts/functions: support usage of dns
    after configure_networking. (LP: #1714308)

3063dc1... by Scott Moser on 2017-09-19

Update ubuntu/devel from 0.125ubuntu10 to 0.125ubuntu11

Prior ubuntu/devel commit: 3112eb4aedac6024286b9aa02685ef168abcfb66
New ubuntu/devel commit: 9f473ce57fc209e76962c33bfdb0c287097b3a0e

0b98524... by Scott Moser on 2017-09-29

netinfo_to_resolv_conf: allow writing to '-'

if file name provided is '-', then write to stdout.

Scott Moser (smoser) wrote :

In a discussion with Dimitri, it was suggested that one way to transition
the link to systemd-networkd more fully would be to write files like:
  /run/systemd/netif/links/20
and
  /run/systemd/netif/leases/20

Then it is believed that systemd-networkd would even manage the dhcp link
correctly.

One question this brings up in my mind, is what should/will happen when a
dhcp lease is up on an interface when a network filesystem or block
device resides on that link? This isn't specific at all to initramfs
transition as it would apply to any dhcp-configured network device that
mounts network filesystem.

As an example, of content, in an lxc container I have:

# cat /run/systemd/netif/leases/20
# This is private data. Do not parse.
ADDRESS=10.75.205.194
NETMASK=255.255.255.0
ROUTER=10.75.205.1
SERVER_ADDRESS=10.75.205.1
NEXT_SERVER=10.75.205.1
BROADCAST=10.75.205.255
T1=1800
T2=3150
LIFETIME=3600
DNS=10.75.205.1
DOMAINNAME=lxd
HOSTNAME=a1
CLIENTID=ffdeb2597a00020000ab1156b04a522c37f831

# cat /run/systemd/netif/links/20
# This is private data. Do not parse.
ADMIN_STATE=configured
OPER_STATE=routable
NETWORK_FILE=/run/systemd/network/10-netplan-eth0.network
DNS=10.75.205.1 fd42:eee5:7c43:3d62::1 fe80::9cb9:7aff:fea4:429
NTP=
DOMAINS=lxd
ROUTE_DOMAINS=
LLMNR=yes
MDNS=no
ADDRESSES=fd42:eee5:7c43:3d62:b106:9773:17c6:52ca/128 10.75.205.194/24
ROUTES=::/0/0/100/254/4186785205 fd42:eee5:7c43:3d62::/64/0/100/254/5986785205 0.0.0.0/0/0/100/254/18446744073709551615 10.75.205.1/32/0/100/254/18446744073709551615
DHCP4_ADDRESS=10.75.205.194
DHCP_LEASE=/run/systemd/netif/leases/20

Unmerged commits

6b8d55b... by Scott Moser on 2017-09-05

update changelog (netplan writing)

aabc1e0... by Scott Moser on 2017-09-05

add netplan tests.

0b98524... by Scott Moser on 2017-09-29

netinfo_to_resolv_conf: allow writing to '-'

if file name provided is '-', then write to stdout.

1d11695... by Scott Moser on 2017-09-05

scripts/functions: support netplan writing

3063dc1... by Scott Moser on 2017-09-19

Update ubuntu/devel from 0.125ubuntu10 to 0.125ubuntu11

Prior ubuntu/devel commit: 3112eb4aedac6024286b9aa02685ef168abcfb66
New ubuntu/devel commit: 9f473ce57fc209e76962c33bfdb0c287097b3a0e

9f473ce... by Scott Moser on 2017-09-19

Import patches-unapplied version 0.125ubuntu11 to ubuntu/artful-proposed

Imported using git-ubuntu import.

Publish parent: 48b52ea2b8d6699c5c09e01967bae4e276bc3ca9

New changelog entries:
  * hook-functions, mkinitramfs, scripts/functions: support usage of dns
    after configure_networking. (LP: #1714308)

48b52ea... by Andy Whitcroft on 2017-08-30

Import patches-unapplied version 0.125ubuntu10 to ubuntu/artful-proposed

Imported using git-ubuntu import.

Publish parent: c210559c01d5a59930831f5509d061b566c3458f

New changelog entries:
  * hook-functions: include backported bnxt driver. (LP: #1712491)

c210559... by LaMont Jones on 2016-12-15

Import patches-unapplied version 0.125ubuntu9 to ubuntu/artful

Imported using usd-importer.

Publish parent: e0f307c4463f01c2ce92a76bb96d4c6f2226c75e

e0f307c... by LaMont Jones on 2016-12-15

Import patches-unapplied version 0.125ubuntu9 to ubuntu/zesty

Imported using usd-importer.

Publish parent: 9fcb9e51603f604f2e621d9db90d5c986aaef1a9
Changelog parent: 59cf727709343de7314164e01370850136c19f95

59cf727... by LaMont Jones on 2016-12-15

Import patches-unapplied version 0.125ubuntu9 to ubuntu/zesty-proposed

Imported using usd-importer.

Publish parent: 15a3e4b44a9af92961b05d87adc20fde799bcc00

New changelog entries:
  [ Mathieu Trudel-Lapierre ]
  * Use configure_networking from yakkety-proposed (SRU), addressing various
    review feedback. dhclient -4 will be reconsidered later. LP: #1621507

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

Subscribers

People subscribed via source and target branches