Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Jun 2025 07:20:26 GMT
From:      Baptiste Daroussin <bapt@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 09545628f0cd - main - nuageinit: fix using user_data as a script
Message-ID:  <202506100720.55A7KQSG045031@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=09545628f0cd58406a47f302fb8584a5292d4b1a

commit 09545628f0cd58406a47f302fb8584a5292d4b1a
Author:     Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2025-06-10 07:09:47 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2025-06-10 07:20:23 +0000

    nuageinit: fix using user_data as a script
    
    In official cloudinit, when a user_data file starts with '#!' it
    should be execute late in the boot process. To respect this nuageinit
    now copy the user_data script into a /var/cache/nuageinit/user_data if
    found and a new "firsboot" rcscript anchored to the 'local' rc script is
    responsible to execute it if found.
    
    Note by doing this, we fix another issue we had with nuageinit, if the
    cloudinit provider provides the user_data scriptout with the executable
    permission, previous implementation was not working, like apparently
    what Digital Ocean is doing.
    
    PR:             287183
    Reported by:    olgeni@
---
 libexec/nuageinit/nuageinit                | 15 ++++++++++-----
 libexec/nuageinit/tests/nuageinit.sh       | 30 ++++++++++++++++++++++++++++--
 libexec/rc/rc.d/Makefile                   |  3 ++-
 libexec/rc/rc.d/nuageinit_user_data_script | 25 +++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit
index dda3ae482859..f2f15f0d36f0 100755
--- a/libexec/nuageinit/nuageinit
+++ b/libexec/nuageinit/nuageinit
@@ -396,9 +396,14 @@ if line == "#cloud-config" then
 	if obj.package_upgrade then
 		nuage.upgrade_packages()
 	end
-else
-	local res, err = os.execute(path .. "/" .. ud)
-	if not res then
-		nuage.err("error executing user-data script: " .. err)
-	end
+elseif line:sub(1, 2) == "#!" then
+	-- delay for execution at rc.local time --
+	f = io.open(path .. "/" .. ud)
+	local content = f:read("*a")
+	f:close()
+	nuage.mkdir_p(root .. "/var/cache/nuageinit")
+	f = assert(io.open(root .. "/var/cache/nuageinit/user_data", "w"))
+	f:write(content)
+	f:close()
+	sys_stat.chmod(root .. "/var/cache/nuageinit/user_data", 493)
 end
diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh
index 5fc811f1dcb5..be8b186d933b 100644
--- a/libexec/nuageinit/tests/nuageinit.sh
+++ b/libexec/nuageinit/tests/nuageinit.sh
@@ -27,6 +27,7 @@ atf_test_case config2_userdata_runcmd
 atf_test_case config2_userdata_packages
 atf_test_case config2_userdata_update_packages
 atf_test_case config2_userdata_upgrade_packages
+atf_test_case config2_userdata_shebang
 
 setup_test_adduser()
 {
@@ -73,7 +74,8 @@ nocloud_userdata_script_body()
 	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
 	printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user-data
 	chmod 755 "${PWD}"/media/nuageinit/user-data
-	atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
+	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
+	atf_check -o inline:"#!/bin/sh\necho yeah\n" cat var/cache/nuageinit/user_data
 }
 
 nocloud_user_data_script_body()
@@ -82,7 +84,8 @@ nocloud_user_data_script_body()
 	printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
 	printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user_data
 	chmod 755 "${PWD}"/media/nuageinit/user_data
-	atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
+	atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
+	atf_check -o inline:"#!/bin/sh\necho yeah\n" cat var/cache/nuageinit/user_data
 }
 
 nocloud_userdata_cloudconfig_users_head()
@@ -810,6 +813,28 @@ EOF
 	atf_check -o inline:"pkg upgrade -y\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
 }
 
+config2_userdata_shebang_body()
+{
+	mkdir -p media/nuageinit
+	setup_test_adduser
+	printf "{}" > media/nuageinit/meta_data.json
+	cat > media/nuageinit/user_data <<EOF
+#!/we/dont/care
+anything
+EOF
+	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
+	test -f var/cache/nuageinit/user_data || atf_fail "File not created"
+	test -x var/cache/nuageinit/user_data || atf_fail "Missing execution permission"
+	atf_check -o inline:"#!/we/dont/care\nanything\n" cat var/cache/nuageinit/user_data
+	cat > media/nuageinit/user_data <<EOF
+/we/dont/care
+EOF
+	rm var/cache/nuageinit/user_data
+	if [ -f var/cache/nuageinit/user_data ]; then
+		atf_fail "File should not have been created"
+	fi
+}
+
 atf_init_test_cases()
 {
 	atf_add_test_case args
@@ -833,4 +858,5 @@ atf_init_test_cases()
 	atf_add_test_case config2_userdata_packages
 	atf_add_test_case config2_userdata_update_packages
 	atf_add_test_case config2_userdata_upgrade_packages
+	atf_add_test_case config2_userdata_shebang
 }
diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile
index 4696ef223378..b505d33c68f3 100644
--- a/libexec/rc/rc.d/Makefile
+++ b/libexec/rc/rc.d/Makefile
@@ -367,7 +367,8 @@ SMRCDPACKAGE=	sendmail
 
 .if ${MK_NUAGEINIT} != "no"
 CONFGROUPS+=	NIUAGEINIT
-NIUAGEINIT=		nuageinit
+NIUAGEINIT=		nuageinit \
+			nuageinit_user_data_script
 NIUAGEINITPACKAGE=	nuageinit
 .endif
 
diff --git a/libexec/rc/rc.d/nuageinit_user_data_script b/libexec/rc/rc.d/nuageinit_user_data_script
new file mode 100755
index 000000000000..94d5d008a7fc
--- /dev/null
+++ b/libexec/rc/rc.d/nuageinit_user_data_script
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+
+# PROVIDE: nuageinit_user_data_script
+# REQUIRE: local
+# KEYWORD: firstboot
+
+. /etc/rc.subr
+
+name="nuageinit_user_data_script"
+desc="Execute user data script provided by cloudinit"
+start_cmd="execute_user_data_script"
+stop_cmd=":"
+rcvar="nuageinit_enable"
+
+execute_user_data_script()
+{
+	test -x /var/cache/nuageinit/user_data || return
+	echo "Executing user_data script" | tee -a /var/log/nuageinnit.log
+	/var/cache/nuageinit/user_data 2>&1 | tee -a /var/log/nuageinit.log
+}
+
+# Share the same config as nuageinit
+load_rc_config nuageinit
+run_rc_command "$1"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506100720.55A7KQSG045031>