1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2016
set -eux
set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
at_exit() {
set +e
machinectl kill --signal=KILL nss-mymachines-{noip,singleip,manyips}
mountpoint -q /var/lib/machines && timeout 10 sh -c "until umount /var/lib/machines; do sleep .5; done"
rm -f /run/systemd/nspawn/*.nspawn
}
trap at_exit EXIT
# Mount temporary directory over /var/lib/machines to not pollute the image
mkdir -p /var/lib/machines
mount --bind "$(mktemp --tmpdir=/var/tmp -d)" /var/lib/machines
# Create a bunch of containers that:
# 1) Have no IP addresses assigned
create_dummy_container /var/lib/machines/nss-mymachines-noip
cat >/var/lib/machines/nss-mymachines-noip/sbin/init <<\EOF
#!/usr/bin/bash -ex
ip addr show dev ve-noip
touch /initialized
sleep infinity &
# Run the sleep command asynchronously, so bash is able to process signals
while :; do
wait || :
done
EOF
# 2) Have one IP address assigned (IPv4 only)
create_dummy_container /var/lib/machines/nss-mymachines-singleip
cat >/var/lib/machines/nss-mymachines-singleip/sbin/init <<\EOF
#!/usr/bin/bash -ex
ip addr add 10.1.0.2/24 dev ve-singleip
ip addr show dev ve-singleip
touch /initialized
sleep infinity &
while :; do
wait || :
done
EOF
# 3) Have bunch of IP addresses assigned (both IPv4 and IPv6)
create_dummy_container /var/lib/machines/nss-mymachines-manyips
cat >/var/lib/machines/nss-mymachines-manyips/sbin/init <<\EOF
#!/usr/bin/bash -ex
ip addr add 10.2.0.2/24 dev ve-manyips
for i in {100..120}; do
ip addr add 10.2.0.$i/24 dev ve-manyips
done
ip addr add fd00:dead:beef:cafe::2/64 dev ve-manyips nodad
ip addr show dev ve-manyips
touch /initialized
sleep infinity
while :; do
wait || :
done
EOF
# Create the respective .nspawn config files
mkdir -p /run/systemd/nspawn
for container in noip singleip manyips; do
cat >"/run/systemd/nspawn/nss-mymachines-$container.nspawn" <<EOF
[Exec]
Boot=yes
[Network]
VirtualEthernetExtra=ve-$container
EOF
done
# Start the containers and wait until all of them are initialized
machinectl start nss-mymachines-{noip,singleip,manyips}
for container in nss-mymachines-{noip,singleip,manyips}; do
timeout 30 bash -xec "while [[ ! -e /var/lib/machines/$container/initialized ]]; do sleep .5; done"
done
# We need to configure the dummy interfaces on the "outside" as well for `getent {ahosts4,ahosts6}` to work
# properly. This is caused by getaddrinfo() calling _check_pf() that iterates through all interfaces and
# notes if any of them has an IPv4/IPv6 - this is then used together with AF_INET/AF_INET6 to determine if we
# can ever return a valid answer, and if we configured the container interfaces only in the container, we
# would have no valid IPv4/IPv6 on the "outside" (as we don't set up any other netdev) which would make
# getaddrinfo() return EAI_NONAME without ever asking nss-mymachines.
ip addr add 10.1.0.1/24 dev ve-singleip
ip addr add 10.2.0.1/24 dev ve-manyips
ip addr add fd00:dead:beef:cafe::1/64 dev ve-manyips nodad
getent hosts -s mymachines
getent ahosts -s mymachines
# And finally check if we can resolve the containers via nss-mymachines
for database in hosts ahosts{,v4,v6}; do
(! getent "$database" -s mymachines nss-mymachines-noip)
done
run_and_grep "^10\.1\.0\.2\s+nss-mymachines-singleip$" getent hosts -s mymachines nss-mymachines-singleip
run_and_grep "^10\.1\.0\.2\s+STREAM" getent ahosts -s mymachines nss-mymachines-singleip
run_and_grep "^10\.1\.0\.2\s+STREAM" getent ahostsv4 -s mymachines nss-mymachines-singleip
run_and_grep "^::ffff:10\.1\.0\.2\s+STREAM" getent ahostsv6 -s mymachines nss-mymachines-singleip
run_and_grep "^fd00:dead:beef:cafe::2\s+nss-mymachines-manyips$" getent hosts -s mymachines nss-mymachines-manyips
run_and_grep "^fd00:dead:beef:cafe::2\s+STREAM" getent ahosts -s mymachines nss-mymachines-manyips
run_and_grep "^10\.2\.0\.2\s+STREAM" getent ahosts -s mymachines nss-mymachines-manyips
for i in {100..120}; do
run_and_grep "^10\.2\.0\.$i\s+STREAM" getent ahosts -s mymachines nss-mymachines-manyips
run_and_grep "^10\.2\.0\.$i\s+STREAM" getent ahostsv4 -s mymachines nss-mymachines-manyips
done
run_and_grep "^fd00:dead:beef:cafe::2\s+STREAM" getent ahostsv6 -s mymachines nss-mymachines-manyips
(! run_and_grep "^fd00:" getent ahostsv4 -s mymachines nss-mymachines-manyips)
(! run_and_grep "^10\.2:" getent ahostsv6 -s mymachines nss-mymachines-manyips)
# Multiple machines at once
run_and_grep "^10\.1\.0\.2\s+nss-mymachines-singleip$" getent hosts -s mymachines nss-mymachines-{singleip,manyips}
run_and_grep "^fd00:dead:beef:cafe::2\s+nss-mymachines-manyips$" getent hosts -s mymachines nss-mymachines-{singleip,manyips}
run_and_grep "^10\.1\.0\.2\s+STREAM" getent ahosts -s mymachines nss-mymachines-{singleip,manyips}
run_and_grep "^10\.2\.0\.2\s+STREAM" getent ahosts -s mymachines nss-mymachines-{singleip,manyips}
run_and_grep "^fd00:dead:beef:cafe::2\s+STREAM" getent ahosts -s mymachines nss-mymachines-{singleip,manyips}
for database in hosts ahosts ahostsv4 ahostsv6; do
(! getent "$database" -s mymachines foo-bar-baz)
done
# getgrid(), getgrnam(), getpwuid(), and getpwnam() are explicitly handled by nss-mymachines, so probe them
# as well
(! getent group -s mymachines foo 11)
(! getent passwd -s mymachines foo 11)
machinectl stop nss-mymachines-{noip,singleip,manyips}
|