xref: /freebsd/libexec/nuageinit/tests/nuageinit.sh (revision b56d2195f124d48ce54369d179aa1d4663e5e64a)
1#-
2# Copyright (c) 2022-2025 Baptiste Daroussin <bapt@FreeBSD.org>
3#
4# SPDX-License-Identifier: BSD-2-Clause
5#
6
7export NUAGE_FAKE_ROOTDIR="$PWD"
8
9atf_test_case args
10atf_test_case nocloud
11atf_test_case nocloud_userdata_script
12atf_test_case nocloud_user_data_script
13atf_test_case nocloud_userdata_cloudconfig_users
14atf_test_case nocloud_network
15atf_test_case config2
16atf_test_case config2_pubkeys
17atf_test_case config2_pubkeys_user_data
18atf_test_case config2_pubkeys_meta_data
19atf_test_case config2_network
20atf_test_case config2_network_static_v4
21atf_test_case config2_ssh_keys
22atf_test_case nocloud_userdata_cloudconfig_ssh_pwauth
23atf_test_case nocloud_userdata_cloudconfig_chpasswd
24atf_test_case nocloud_userdata_cloudconfig_chpasswd_list_string
25atf_test_case nocloud_userdata_cloudconfig_chpasswd_list_list
26atf_test_case config2_userdata_runcmd
27atf_test_case config2_userdata_packages
28atf_test_case config2_userdata_update_packages
29atf_test_case config2_userdata_upgrade_packages
30atf_test_case config2_userdata_shebang
31atf_test_case config2_userdata_fqdn_and_hostname
32atf_test_case config2_userdata_write_files
33
34setup_test_adduser()
35{
36	here=$(pwd)
37	export NUAGE_FAKE_ROOTDIR=$(pwd)
38	mkdir -p etc/ssh
39	cat > etc/master.passwd << EOF
40root:*:0:0::0:0:Charlie &:/root:/bin/csh
41sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
42EOF
43	pwd_mkdb -d etc ${here}/etc/master.passwd
44	cat > etc/group << EOF
45wheel:*:0:root
46users:*:1:
47EOF
48}
49
50args_body()
51{
52	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit
53	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit bla
54	atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit bla meh plop
55	atf_check -s exit:1 -e inline:"nuageinit: Unknown cloud init type: meh\n" /usr/libexec/nuageinit bla meh
56}
57
58nocloud_body()
59{
60	mkdir -p media/nuageinit
61	atf_check -s exit:1 -e match:"nuageinit: error parsing nocloud.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit/ nocloud
62	printf "instance-id: iid-local01\nlocal-hostname: cloudimg\n" > "${PWD}"/media/nuageinit/meta-data
63	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
64	atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
65	cat > media/nuageinit/meta-data << EOF
66instance-id: iid-local01
67hostname: myhost
68EOF
69	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
70	atf_check -o inline:"hostname=\"myhost\"\n" cat etc/rc.conf.d/hostname
71}
72
73nocloud_userdata_script_body()
74{
75	mkdir -p media/nuageinit
76	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
77	printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user-data
78	chmod 755 "${PWD}"/media/nuageinit/user-data
79	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
80	atf_check -o inline:"#!/bin/sh\necho yeah\n" cat var/cache/nuageinit/user_data
81}
82
83nocloud_user_data_script_body()
84{
85	mkdir -p media/nuageinit
86	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
87	printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user_data
88	chmod 755 "${PWD}"/media/nuageinit/user_data
89	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
90	atf_check -o inline:"#!/bin/sh\necho yeah\n" cat var/cache/nuageinit/user_data
91}
92
93nocloud_userdata_cloudconfig_users_head()
94{
95	atf_set "require.user" root
96}
97nocloud_userdata_cloudconfig_users_body()
98{
99	mkdir -p media/nuageinit
100	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
101	mkdir -p etc
102	cat > etc/master.passwd << EOF
103root:*:0:0::0:0:Charlie &:/root:/bin/sh
104sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
105EOF
106	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
107	cat > etc/group << EOF
108wheel:*:0:root
109users:*:1:
110EOF
111	cat > media/nuageinit/user-data << 'EOF'
112#cloud-config
113groups:
114  - admingroup: [root,sys]
115  - cloud-users
116users:
117  - default
118  - name: foobar
119    gecos: Foo B. Bar
120    primary_group: foobar
121    sudo: ALL=(ALL) NOPASSWD:ALL
122    groups: users
123    passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
124  - name: bla
125    sudo:
126    - "ALL=(ALL) NOPASSWD:/usr/sbin/pw"
127    - "ALL=(ALL) ALL"
128EOF
129	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
130	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
131	cat > expectedgroup << EOF
132wheel:*:0:root,freebsd
133users:*:1:foobar
134admingroup:*:1001:root,sys
135cloud-users:*:1002:
136freebsd:*:1003:
137foobar:*:1004:
138bla:*:1005:
139EOF
140	cat > expectedpasswd << 'EOF'
141root:*:0:0::0:0:Charlie &:/root:/bin/sh
142sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
143freebsd:freebsd:1001:1003::0:0:FreeBSD User:/home/freebsd:/bin/sh
144foobar:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1002:1004::0:0:Foo B. Bar:/home/foobar:/bin/sh
145bla::1003:1005::0:0:bla User:/home/bla:/bin/sh
146EOF
147	sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" "${PWD}"/etc/master.passwd
148	atf_check -o file:expectedpasswd cat "${PWD}"/etc/master.passwd
149	atf_check -o file:expectedgroup cat "${PWD}"/etc/group
150	atf_check -o inline:"foobar ALL=(ALL) NOPASSWD:ALL\nbla ALL=(ALL) NOPASSWD:/usr/sbin/pw\nbla ALL=(ALL) ALL\n" cat ${PWD}/usr/local/etc/sudoers.d/90-nuageinit-users
151}
152
153nocloud_network_head()
154{
155	atf_set "require.user" root
156}
157nocloud_network_body()
158{
159	mkdir -p media/nuageinit
160	mkdir -p etc
161	cat > etc/master.passwd << EOF
162root:*:0:0::0:0:Charlie &:/root:/bin/sh
163sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
164EOF
165	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
166	cat > etc/group << EOF
167wheel:*:0:root
168users:*:1:
169EOF
170	mynetworks=$(ifconfig -l ether)
171	if [ -z "$mynetworks" ]; then
172		atf_skip "a network interface is needed"
173	fi
174	set -- $mynetworks
175	myiface=$1
176	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
177	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
178	cat > media/nuageinit/user-data << EOF
179#cloud-config
180network:
181  version: 2
182  ethernets:
183    # opaque ID for physical interfaces, only referred to by other stanzas
184    id0:
185      match:
186        macaddress: "$myaddr"
187      addresses:
188        - 192.0.2.2/24
189        - 2001:db8::2/64
190      gateway4: 192.0.2.1
191      gateway6: 2001:db8::1
192EOF
193	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
194	cat > network << EOF
195ifconfig_${myiface}="inet 192.0.2.2/24"
196ifconfig_${myiface}_ipv6="inet6 2001:db8::2/64"
197ipv6_network_interfaces="${myiface}"
198ipv6_default_interface="${myiface}"
199EOF
200	cat > routing << EOF
201defaultrouter="192.0.2.1"
202ipv6_defaultrouter="2001:db8::1"
203ipv6_route_${myiface}="2001:db8::1 -prefixlen 128 -interface ${myiface}"
204EOF
205	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
206	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
207}
208
209config2_body()
210{
211	mkdir -p media/nuageinit
212	atf_check -s exit:1 -e match:"nuageinit: error parsing config-2 meta_data.json:.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
213	printf "{}" > media/nuageinit/meta_data.json
214	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
215	cat > media/nuageinit/meta_data.json << EOF
216{
217    "hostname": "cloudimg"
218}
219EOF
220	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
221	atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
222}
223
224config2_pubkeys_head()
225{
226	atf_set "require.user" root
227}
228config2_pubkeys_body()
229{
230	mkdir -p media/nuageinit
231	touch media/nuageinit/meta_data.json
232	cat > media/nuageinit/user-data << EOF
233#cloud-config
234ssh_authorized_keys:
235  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
236EOF
237	mkdir -p etc
238	cat > etc/master.passwd << EOF
239root:*:0:0::0:0:Charlie &:/root:/bin/sh
240sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
241EOF
242	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
243	cat > etc/group << EOF
244wheel:*:0:root
245users:*:1:
246EOF
247	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
248	atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys
249}
250
251config2_pubkeys_user_data_head()
252{
253	atf_set "require.user" root
254}
255config2_pubkeys_user_data_body()
256{
257	mkdir -p media/nuageinit
258	touch media/nuageinit/meta_data.json
259	cat > media/nuageinit/user_data << EOF
260#cloud-config
261ssh_authorized_keys:
262  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
263EOF
264	mkdir -p etc
265	cat > etc/master.passwd << EOF
266root:*:0:0::0:0:Charlie &:/root:/bin/sh
267sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
268EOF
269	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
270	cat > etc/group << EOF
271wheel:*:0:root
272users:*:1:
273EOF
274	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
275	atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys
276}
277
278config2_pubkeys_meta_data_body()
279{
280	here=$(pwd)
281	export NUAGE_FAKE_ROOTDIR=$(pwd)
282	if [ $(id -u) -ne 0 ]; then
283		atf_skip "root required"
284	fi
285	mkdir -p media/nuageinit
286	cat > media/nuageinit/meta_data.json << EOF
287{
288    "uuid": "uuid_for_this_instance",
289    "admin_pass": "a_generated_password",
290    "public_keys": {
291        "tdb": "ssh-ed25519 my_key_id tdb@host"
292    },
293    "keys": [
294        {
295            "name": "tdb",
296            "type": "ssh",
297            "data": "ssh-ed25519 my_key_id tdb@host"
298        }
299    ],
300    "hostname": "freebsd-14-test.novalocal",
301    "name": "freebsd-14-test",
302    "launch_index": 0,
303    "availability_zone": "nova",
304    "random_seed": "long_random_seed",
305    "project_id": "my_project_id",
306    "devices": [],
307    "dedicated_cpus": []
308}
309EOF
310	mkdir -p etc
311	cat > etc/master.passwd << EOF
312root:*:0:0::0:0:Charlie &:/root:/bin/csh
313sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
314EOF
315	pwd_mkdb -d etc ${here}/etc/master.passwd
316	cat > etc/group << EOF
317wheel:*:0:root
318users:*:1:
319EOF
320	atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2
321	atf_check -o inline:"ssh-ed25519 my_key_id tdb@host\n" cat home/freebsd/.ssh/authorized_keys
322}
323
324config2_network_body()
325{
326	mkdir -p media/nuageinit
327	printf "{}" > media/nuageinit/meta_data.json
328	mynetworks=$(ifconfig -l ether)
329	if [ -z "$mynetworks" ]; then
330		atf_skip "a network interface is needed"
331	fi
332	set -- $mynetworks
333	myiface=$1
334	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
335cat > media/nuageinit/network_data.json << EOF
336{
337    "links": [
338        {
339            "ethernet_mac_address": "$myaddr",
340            "id": "iface0",
341            "mtu": null
342        }
343    ],
344    "networks": [
345        {
346            "id": "network0",
347            "link": "iface0",
348            "type": "ipv4_dhcp"
349        },
350        { // IPv6
351            "id": "private-ipv4",
352            "type": "ipv6",
353            "link": "iface0",
354            // supports condensed IPv6 with CIDR netmask
355            "ip_address": "2001:db8::3257:9652/64",
356            "gateway": "fd00::1",
357            "routes": [
358                {
359                    "network": "::",
360                    "netmask": "::",
361                    "gateway": "fd00::1"
362                },
363                {
364                    "network": "::",
365                    "netmask": "ffff:ffff:ffff::",
366                    "gateway": "fd00::1:1"
367                }
368            ],
369            "network_id": "da5bb487-5193-4a65-a3df-4a0055a8c0d8"
370        }
371    ]
372}
373EOF
374	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
375	cat > network << EOF
376ifconfig_${myiface}="DHCP"
377ifconfig_${myiface}_ipv6="inet6 2001:db8::3257:9652/64"
378ipv6_network_interfaces="${myiface}"
379ipv6_default_interface="${myiface}"
380EOF
381	cat > routing << EOF
382ipv6_defaultrouter="fd00::1"
383ipv6_route_${myiface}="fd00::1 -prefixlen 128 -interface ${myiface}"
384ipv6_static_routes="${myiface}"
385EOF
386	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
387	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
388}
389
390config2_network_static_v4_body()
391{
392	mkdir -p media/nuageinit
393	printf "{}" > media/nuageinit/meta_data.json
394	mynetworks=$(ifconfig -l ether)
395	if [ -z "$mynetworks" ]; then
396		atf_skip "a network interface is needed"
397	fi
398	set -- $mynetworks
399	myiface=$1
400	myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
401cat > media/nuageinit/network_data.json << EOF
402{
403    "links": [
404        {
405            "ethernet_mac_address": "$myaddr",
406            "id": "iface0",
407            "mtu": null
408        }
409    ],
410    "networks": [
411        {
412            "id": "network0",
413            "link": "iface0",
414            "type": "ipv4",
415            "ip_address": "10.184.0.244",
416            "netmask": "255.255.240.0",
417            "routes": [
418                {
419                    "network": "10.0.0.0",
420                    "netmask": "255.0.0.0",
421                    "gateway": "11.0.0.1"
422                },
423                {
424                    "network": "0.0.0.0",
425                    "netmask": "0.0.0.0",
426                    "gateway": "23.253.157.1"
427                }
428            ]
429        }
430    ]
431}
432EOF
433	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
434	cat > network << EOF
435ifconfig_${myiface}="inet 10.184.0.244 netmask 255.255.240.0"
436EOF
437	cat > routing << EOF
438route_cloudinit1_${myiface}="-net 10.0.0.0 11.0.0.1 255.0.0.0"
439defaultrouter="23.253.157.1"
440static_routes="cloudinit1_${myiface}"
441EOF
442	atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
443	atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
444}
445
446config2_ssh_keys_head()
447{
448	atf_set "require.user" root
449}
450config2_ssh_keys_body()
451{
452	here=$(pwd)
453	export NUAGE_FAKE_ROOTDIR=$(pwd)
454	mkdir -p media/nuageinit
455	touch media/nuageinit/meta_data.json
456	cat > media/nuageinit/user-data << EOF
457#cloud-config
458ssh_keys:
459  rsa_private: |
460    -----BEGIN RSA PRIVATE KEY-----
461    MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qco
462    ...
463    -----END RSA PRIVATE KEY-----
464  rsa_public: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEAoPRhIfLvedSDKw7Xd ...
465  ed25519_private: |
466    -----BEGIN OPENSSH PRIVATE KEY-----
467    blabla
468    ...
469    -----END OPENSSH PRIVATE KEY-----
470  ed25519_public: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+MH4E8KO32N5CXRvXVqvyZVl0+6ue4DobdhU0FqFd+
471EOF
472	mkdir -p etc/ssh
473	cat > etc/master.passwd << EOF
474root:*:0:0::0:0:Charlie &:/root:/bin/csh
475sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
476EOF
477	pwd_mkdb -d etc ${here}/etc/master.passwd
478	cat > etc/group << EOF
479wheel:*:0:root
480users:*:1:
481EOF
482	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
483	_expected="-----BEGIN RSA PRIVATE KEY-----
484MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qco
485...
486-----END RSA PRIVATE KEY-----
487
488"
489	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_rsa_key
490	_expected="ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEAoPRhIfLvedSDKw7Xd ...\n"
491	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_rsa_key.pub
492	_expected="-----BEGIN OPENSSH PRIVATE KEY-----
493blabla
494...
495-----END OPENSSH PRIVATE KEY-----
496
497"
498	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_ed25519_key
499	_expected="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+MH4E8KO32N5CXRvXVqvyZVl0+6ue4DobdhU0FqFd+\n"
500	atf_check -o inline:"${_expected}" cat ${PWD}/etc/ssh/ssh_host_ed25519_key.pub
501}
502
503
504nocloud_userdata_cloudconfig_ssh_pwauth_head()
505{
506	atf_set "require.user" root
507}
508nocloud_userdata_cloudconfig_ssh_pwauth_body()
509{
510	mkdir -p etc
511	cat > etc/master.passwd << EOF
512root:*:0:0::0:0:Charlie &:/root:/bin/sh
513sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
514EOF
515	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
516	cat > etc/group << EOF
517wheel:*:0:root
518users:*:1:
519EOF
520	mkdir -p media/nuageinit
521	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
522	cat > media/nuageinit/user-data << 'EOF'
523#cloud-config
524ssh_pwauth: true
525EOF
526	mkdir -p etc/ssh/
527	touch etc/ssh/sshd_config
528
529	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
530	atf_check -o inline:"PasswordAuthentication yes\n" cat etc/ssh/sshd_config
531
532	# Same value we don't touch anything
533	printf "   PasswordAuthentication yes # I want password\n" > etc/ssh/sshd_config
534	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
535	atf_check -o inline:"   PasswordAuthentication yes # I want password\n" cat etc/ssh/sshd_config
536
537	printf "   PasswordAuthentication no # Should change\n" > etc/ssh/sshd_config
538	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
539	atf_check -o inline:"PasswordAuthentication yes\n" cat etc/ssh/sshd_config
540
541	cat > media/nuageinit/user-data << 'EOF'
542#cloud-config
543ssh_pwauth: false
544EOF
545
546	printf "   PasswordAuthentication no # no passwords\n" > etc/ssh/sshd_config
547	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
548	atf_check -o inline:"   PasswordAuthentication no # no passwords\n" cat etc/ssh/sshd_config
549
550	printf "   PasswordAuthentication yes # Should change\n" > etc/ssh/sshd_config
551	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
552	atf_check -o inline:"PasswordAuthentication no\n" cat etc/ssh/sshd_config
553}
554
555nocloud_userdata_cloudconfig_chpasswd_head()
556{
557	atf_set "require.user" root
558}
559nocloud_userdata_cloudconfig_chpasswd_body()
560{
561	mkdir -p etc
562	cat > etc/master.passwd << EOF
563root:*:0:0::0:0:Charlie &:/root:/bin/sh
564sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
565user:*:1:0::0:0:Sys:/home/sys:/bin/sh
566EOF
567	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
568	cat > etc/group << EOF
569wheel:*:0:root
570users:*:1:
571EOF
572	mkdir -p media/nuageinit
573	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
574	cat > media/nuageinit/user-data << 'EOF'
575#cloud-config
576chpasswd:
577  expire: true
578  users:
579  - { user: "sys", password: RANDOM }
580EOF
581
582	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
583	atf_check -o empty -e inline:"nuageinit: Invalid entry for chpasswd.users: missing 'name'\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
584	# nothing modified
585	atf_check -o inline:"sys:*:1:0::0:0:Sys:/home/sys:/bin/sh\n" pw -R $(pwd) usershow sys
586
587	cat > media/nuageinit/user-data << 'EOF'
588#cloud-config
589chpasswd:
590  expire: true
591  users:
592  - { name: "sys", pwd: RANDOM }
593EOF
594	atf_check -o empty -e inline:"nuageinit: Invalid entry for chpasswd.users: missing 'password'\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
595	# nothing modified
596	atf_check -o inline:"sys:*:1:0::0:0:Sys:/home/sys:/bin/sh\n" pw -R $(pwd) usershow sys
597
598	cat > media/nuageinit/user-data << 'EOF'
599#cloud-config
600chpasswd:
601  expire: false
602  users:
603  - { name: "sys", password: RANDOM }
604EOF
605	# not empty because the password is printed to stdout
606	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
607	atf_check -o match:'sys:\$.*:1:0::0:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
608
609	cat > media/nuageinit/user-data << 'EOF'
610#cloud-config
611chpasswd:
612  expire: true
613  users:
614  - { name: "sys", password: RANDOM }
615EOF
616	# not empty because the password is printed to stdout
617	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
618	atf_check -o match:'sys:\$.*:1:0::1:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
619
620	cat > media/nuageinit/user-data << 'EOF'
621#cloud-config
622chpasswd:
623  expire: true
624  users:
625  - { name: "user", password: "$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/" }
626EOF
627	# not empty because the password is printed to stdout
628	atf_check -o empty -e empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
629	atf_check -o inline:'user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1:0::1:0:Sys:/home/sys:/bin/sh\n' pw -R $(pwd) usershow user
630}
631
632
633nocloud_userdata_cloudconfig_chpasswd_list_string_head()
634{
635	atf_set "require.user" root
636}
637nocloud_userdata_cloudconfig_chpasswd_list_string_body()
638{
639	mkdir -p etc
640	cat > etc/master.passwd << EOF
641root:*:0:0::0:0:Charlie &:/root:/bin/sh
642sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
643user:*:1:0::0:0:Sys:/home/sys:/bin/sh
644EOF
645	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
646	cat > etc/group << EOF
647wheel:*:0:root
648users:*:1:
649EOF
650	mkdir -p media/nuageinit
651	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
652	cat > media/nuageinit/user-data << 'EOF'
653#cloud-config
654chpasswd:
655  expire: true
656  list: |
657     sys:RANDOM
658EOF
659
660	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
661	atf_check -o empty -e inline:"nuageinit: chpasswd.list is deprecated consider using chpasswd.users\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
662	atf_check -o match:'sys:\$.*:1:0::1:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
663
664	cat > media/nuageinit/user-data << 'EOF'
665#cloud-config
666chpasswd:
667  expire: false
668  list: |
669     sys:plop
670     user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
671     root:R
672EOF
673
674	atf_check -o empty -e ignore /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
675	atf_check -o match:'sys:\$.*:1:0::0:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
676	atf_check -o inline:'user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1:0::0:0:Sys:/home/sys:/bin/sh\n' pw -R $(pwd) usershow user
677	atf_check -o match:'root:\$.*:0:0::0:0:Charlie &:/root:/bin/sh$' pw -R $(pwd) usershow root
678}
679
680nocloud_userdata_cloudconfig_chpasswd_list_list_head()
681{
682	atf_set "require.user" root
683}
684nocloud_userdata_cloudconfig_chpasswd_list_list_body()
685{
686	mkdir -p etc
687	cat > etc/master.passwd << EOF
688root:*:0:0::0:0:Charlie &:/root:/bin/sh
689sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
690user:*:1:0::0:0:Sys:/home/sys:/bin/sh
691EOF
692	pwd_mkdb -d etc "${PWD}"/etc/master.passwd
693	cat > etc/group << EOF
694wheel:*:0:root
695users:*:1:
696EOF
697	mkdir -p media/nuageinit
698	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
699	cat > media/nuageinit/user-data << 'EOF'
700#cloud-config
701chpasswd:
702  expire: true
703  list:
704  - sys:RANDOM
705EOF
706
707	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
708	atf_check -o empty -e inline:"nuageinit: chpasswd.list is deprecated consider using chpasswd.users\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
709	atf_check -o match:'sys:\$.*:1:0::1:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
710
711	cat > media/nuageinit/user-data << 'EOF'
712#cloud-config
713chpasswd:
714  expire: false
715  list:
716  - sys:plop
717  - user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
718  - root:R
719EOF
720
721	atf_check -o empty -e ignore /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
722	atf_check -o match:'sys:\$.*:1:0::0:0:Sys:/home/sys:/bin/sh$' pw -R $(pwd) usershow sys
723	atf_check -o inline:'user:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1:0::0:0:Sys:/home/sys:/bin/sh\n' pw -R $(pwd) usershow user
724	atf_check -o match:'root:\$.*:0:0::0:0:Charlie &:/root:/bin/sh$' pw -R $(pwd) usershow root
725}
726
727config2_userdata_runcmd_head()
728{
729	atf_set "require.user" root
730}
731config2_userdata_runcmd_body()
732{
733	mkdir -p media/nuageinit
734	setup_test_adduser
735	printf "{}" > media/nuageinit/meta_data.json
736	cat > media/nuageinit/user_data << 'EOF'
737#cloud-config
738runcmd:
739EOF
740	chmod 755 "${PWD}"/media/nuageinit/user_data
741	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
742	cat > media/nuageinit/user_data << 'EOF'
743#cloud-config
744runcmd:
745  - plop
746EOF
747	chmod 755 "${PWD}"/media/nuageinit/user_data
748	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
749	test -f var/cache/nuageinit/runcmds || atf_fail "File not created"
750	test -x var/cache/nuageinit/runcmds || atf_fail "Missing execution permission"
751	atf_check -o inline:"#!/bin/sh\nplop\n" cat var/cache/nuageinit/runcmds
752
753	cat > media/nuageinit/user_data << 'EOF'
754#cloud-config
755runcmd:
756  - echo "yeah!"
757  - uname -s
758EOF
759	chmod 755 "${PWD}"/media/nuageinit/user_data
760	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
761	atf_check -o inline:"#!/bin/sh\necho \"yeah!\"\nuname -s\n" cat var/cache/nuageinit/runcmds
762}
763
764config2_userdata_packages_head()
765{
766	atf_set "require.user" root
767}
768
769config2_userdata_packages_body()
770{
771	mkdir -p media/nuageinit
772	setup_test_adduser
773	export NUAGE_RUN_TESTS=1
774	printf "{}" > media/nuageinit/meta_data.json
775	cat > media/nuageinit/user_data << 'EOF'
776#cloud-config
777packages:
778EOF
779	chmod 755 "${PWD}"/media/nuageinit/user_data
780	atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
781	cat > media/nuageinit/user_data << 'EOF'
782#cloud-config
783packages:
784  - yeah/plop
785EOF
786	chmod 755 "${PWD}"/media/nuageinit/user_data
787	atf_check -s exit:0 -o inline:"pkg install -y yeah/plop\npkg info -q yeah/plop\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
788
789	cat > media/nuageinit/user_data << 'EOF'
790#cloud-config
791packages:
792  - curl
793EOF
794	chmod 755 "${PWD}"/media/nuageinit/user_data
795	atf_check -o inline:"pkg install -y curl\npkg info -q curl\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
796
797	cat > media/nuageinit/user_data << 'EOF'
798#cloud-config
799packages:
800  - curl
801  - meh: bla
802EOF
803	chmod 755 "${PWD}"/media/nuageinit/user_data
804	atf_check -o inline:"pkg install -y curl\npkg info -q curl\n" -e inline:"nuageinit: Invalid type: table for packages entry number 2\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
805}
806
807config2_userdata_update_packages_body()
808{
809	mkdir -p media/nuageinit
810	setup_test_adduser
811	export NUAGE_RUN_TESTS=1
812	printf "{}" > media/nuageinit/meta_data.json
813	cat > media/nuageinit/user_data << 'EOF'
814#cloud-config
815package_update: true
816EOF
817	chmod 755 "${PWD}"/media/nuageinit/user_data
818	atf_check -o inline:"pkg update -y\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
819}
820
821config2_userdata_upgrade_packages_body()
822{
823	mkdir -p media/nuageinit
824	setup_test_adduser
825	export NUAGE_RUN_TESTS=1
826	printf "{}" > media/nuageinit/meta_data.json
827	cat > media/nuageinit/user_data << 'EOF'
828#cloud-config
829package_upgrade: true
830EOF
831	chmod 755 "${PWD}"/media/nuageinit/user_data
832	atf_check -o inline:"pkg upgrade -y\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
833}
834
835config2_userdata_shebang_body()
836{
837	mkdir -p media/nuageinit
838	setup_test_adduser
839	printf "{}" > media/nuageinit/meta_data.json
840	cat > media/nuageinit/user_data <<EOF
841#!/we/dont/care
842anything
843EOF
844	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
845	test -f var/cache/nuageinit/user_data || atf_fail "File not created"
846	test -x var/cache/nuageinit/user_data || atf_fail "Missing execution permission"
847	atf_check -o inline:"#!/we/dont/care\nanything\n" cat var/cache/nuageinit/user_data
848	cat > media/nuageinit/user_data <<EOF
849/we/dont/care
850EOF
851	rm var/cache/nuageinit/user_data
852	if [ -f var/cache/nuageinit/user_data ]; then
853		atf_fail "File should not have been created"
854	fi
855}
856
857config2_userdata_write_files_body()
858{
859	mkdir -p media/nuageinit
860	setup_test_adduser
861	printf "{}" > media/nuageinit/meta_data.json
862	cat > media/nuageinit/user_data <<EOF
863#cloud-config
864write_files:
865- content: "plop"
866  path: /file1
867- path: /emptyfile
868- content: !!binary |
869    YmxhCg==
870  path: /file_base64
871  encoding: b64
872  permissions: '0755'
873  owner: nobody
874- content: "bob"
875  path: "/foo"
876  defer: true
877EOF
878	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
879	atf_check -o inline:"plop" cat file1
880	atf_check -o inline:"" cat emptyfile
881	atf_check -o inline:"bla\n" cat file_base64
882	test -f foo && atf_fail "foo creation should have been defered"
883	atf_check -o match:"^-rwxr-xr-x.*nobody" ls -l file_base64
884	rm file1 emptyfile file_base64
885	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit postnet
886	test -f file1 -o -f emptyfile -o -f file_base64 && atf_fail "defer not working properly"
887	atf_check -o inline:"bob" cat foo
888}
889
890config2_userdata_fqdn_and_hostname_body()
891{
892	mkdir -p media/nuageinit
893	setup_test_adduser
894	printf "{}" > media/nuageinit/meta_data.json
895	cat > media/nuageinit/user_data <<EOF
896#cloud-config
897fqdn: host.domain.tld
898hostname: host
899EOF
900	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
901	atf_check -o inline:"hostname=\"host.domain.tld\"\n" cat ${PWD}/etc/rc.conf.d/hostname
902	cat > media/nuageinit/user_data <<EOF
903#cloud-config
904hostname: host
905EOF
906	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
907	atf_check -o inline:"hostname=\"host\"\n" cat ${PWD}/etc/rc.conf.d/hostname
908}
909
910atf_init_test_cases()
911{
912	atf_add_test_case args
913	atf_add_test_case nocloud
914	atf_add_test_case nocloud_userdata_script
915	atf_add_test_case nocloud_user_data_script
916	atf_add_test_case nocloud_userdata_cloudconfig_users
917	atf_add_test_case nocloud_network
918	atf_add_test_case config2
919	atf_add_test_case config2_pubkeys
920	atf_add_test_case config2_pubkeys_user_data
921	atf_add_test_case config2_pubkeys_meta_data
922	atf_add_test_case config2_network
923	atf_add_test_case config2_network_static_v4
924	atf_add_test_case config2_ssh_keys
925	atf_add_test_case nocloud_userdata_cloudconfig_ssh_pwauth
926	atf_add_test_case nocloud_userdata_cloudconfig_chpasswd
927	atf_add_test_case nocloud_userdata_cloudconfig_chpasswd_list_string
928	atf_add_test_case nocloud_userdata_cloudconfig_chpasswd_list_list
929	atf_add_test_case config2_userdata_runcmd
930	atf_add_test_case config2_userdata_packages
931	atf_add_test_case config2_userdata_update_packages
932	atf_add_test_case config2_userdata_upgrade_packages
933	atf_add_test_case config2_userdata_shebang
934	atf_add_test_case config2_userdata_fqdn_and_hostname
935	atf_add_test_case config2_userdata_write_files
936}
937