git: 797dad91ff46 - main - nuageinit: implement mounts support
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 05 Jun 2026 11:18:07 UTC
The branch main has been updated by bapt:
URL: https://cgit.FreeBSD.org/src/commit/?id=797dad91ff468a9bd6cd5d4f720eb4bbac1f454a
commit 797dad91ff468a9bd6cd5d4f720eb4bbac1f454a
Author: Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2026-06-05 10:05:08 +0000
Commit: Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2026-06-05 11:15:16 +0000
nuageinit: implement mounts support
Add support for the 'mounts' cloud-config key which configures
mount points by appending entries to /etc/fstab and creating
the corresponding directories.
---
libexec/nuageinit/nuage.lua | 48 +++++++++++++++++++++++++++++++++++-
libexec/nuageinit/nuageinit | 33 +++++++++++++++++++++++++
libexec/nuageinit/nuageinit.7 | 36 +++++++++++++++++++++++++++
libexec/nuageinit/tests/nuageinit.sh | 28 +++++++++++++++++++++
4 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua
index 45e14ef0ce21..34cf8c9fc090 100644
--- a/libexec/nuageinit/nuage.lua
+++ b/libexec/nuageinit/nuage.lua
@@ -821,6 +821,50 @@ local function addfile(file, defer)
return true
end
+local function add_fstab_entry(root, device, mount_point, fstype, options, dump_freq, passno)
+ local fstab_path = root .. "/etc/fstab"
+ local f = io.open(fstab_path, "a")
+ if not f then
+ warnmsg("unable to open " .. fstab_path .. " for writing")
+ return false
+ end
+ options = options or "rw"
+ dump_freq = dump_freq or 0
+ passno = passno or 0
+ f:write(string.format("%s\t\t%s\t\t%s\t\t%s\t\t%d\t\t%d\n",
+ device, mount_point, fstype, options, dump_freq, passno))
+ f:close()
+ return true
+end
+
+local function remove_fstab_entry(root, mount_point)
+ local fstab_path = root .. "/etc/fstab"
+ local f = io.open(fstab_path, "r")
+ if not f then
+ return
+ end
+ local lines = {}
+ for line in f:lines() do
+ local fields = {}
+ for field in line:gmatch("%S+") do
+ table.insert(fields, field)
+ end
+ if fields[2] ~= mount_point then
+ table.insert(lines, line)
+ end
+ end
+ f:close()
+ local nf = io.open(fstab_path, "w")
+ if not nf then
+ warnmsg("unable to open " .. fstab_path .. " for writing")
+ return
+ end
+ for _, line in ipairs(lines) do
+ nf:write(line .. "\n")
+ end
+ nf:close()
+end
+
local n = {
shell_escape = shell_escape,
warn = warnmsg,
@@ -844,7 +888,9 @@ local n = {
upgrade_packages = upgrade_packages,
addsudo = addsudo,
adddoas = adddoas,
- addfile = addfile
+ addfile = addfile,
+ add_fstab_entry = add_fstab_entry,
+ remove_fstab_entry = remove_fstab_entry,
}
return n
diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit
index 9d2f3c6024c4..f56d1207cf01 100755
--- a/libexec/nuageinit/nuageinit
+++ b/libexec/nuageinit/nuageinit
@@ -531,6 +531,38 @@ local function disable_root(obj)
end
end
+local function mounts(obj)
+ if obj.mounts == nil then return end
+ for _, m in ipairs(obj.mounts) do
+ local device, mount_point, fstype, options, dump_freq, passno
+ if type(m) == "table" then
+ if m[1] then
+ -- List format: [device, mount_point, fstype, options, dump_freq, passno]
+ device = m[1]
+ mount_point = m[2]
+ fstype = m[3]
+ options = m[4]
+ dump_freq = tonumber(m[5]) or 0
+ passno = tonumber(m[6]) or 0
+ else
+ -- Dict format
+ device = m.name or m.device or m.spec
+ mount_point = m.mount_point or m.mountpoint
+ fstype = m.type or m.filesystem or m.fstype
+ options = m.options or m.opts
+ dump_freq = tonumber(m.dump) or 0
+ passno = tonumber(m.passno) or tonumber(m.pass_no) or 0
+ end
+ end
+ if device and mount_point and fstype then
+ nuage.mkdir_p(root .. mount_point)
+ nuage.add_fstab_entry(root, device, mount_point, fstype, options, dump_freq, passno)
+ else
+ warnmsg("Invalid mount entry, skipping")
+ end
+ end
+end
+
local function bootcmd(obj)
if obj.bootcmd == nil then return end
local f = nil
@@ -828,6 +860,7 @@ if line == nil then
-- YAML user-data
elseif line == "#cloud-config" then
local pre_network_calls = {
+ mounts,
bootcmd,
sethostname,
manage_etc_hosts,
diff --git a/libexec/nuageinit/nuageinit.7 b/libexec/nuageinit/nuageinit.7
index 66a72324f414..c2981669acb7 100644
--- a/libexec/nuageinit/nuageinit.7
+++ b/libexec/nuageinit/nuageinit.7
@@ -159,6 +159,42 @@ Defaults to
Set to
.Ar false
to skip this behaviour.
+.It Ic mounts
+A list of mount points to configure.
+Each entry is written to
+.Pa /etc/fstab
+and the mount point directory is created.
+.Pp
+Each entry can be specified as a list:
+.Bd -literal -offset indent
+[ device, mountpoint, fstype ]
+.Ed
+.Pp
+or as an object:
+.Bd -literal -offset indent
+{ device: "...", mountpoint: "...", type: "...", options: "..." }
+.Ed
+.Pp
+The following keys are recognized:
+.Bl -tag -width "options"
+.It device (or name, spec)
+The device to mount.
+.It mountpoint (or mount_point)
+The mount point directory.
+.It type (or fstype, filesystem)
+The filesystem type.
+.It options (or opts)
+The mount options, defaults to
+.Qq rw .
+.It dump
+The dump frequency for
+.Xr dump 8 ,
+defaults to 0.
+.It passno
+The pass number for
+.Xr fsck 8 ,
+defaults to 0.
+.El
.It Ic timezone
Sets the system timezone based on the value provided.
.Pp
diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh
index ac7086183d86..11d34fcd98ea 100644
--- a/libexec/nuageinit/tests/nuageinit.sh
+++ b/libexec/nuageinit/tests/nuageinit.sh
@@ -34,6 +34,7 @@ atf_test_case config2_userdata_ssh_deletekeys
atf_test_case config2_userdata_disable_root
atf_test_case config2_userdata_bootcmd
atf_test_case config2_userdata_manage_etc_hosts
+atf_test_case config2_userdata_mounts
atf_test_case config2_userdata_fqdn_and_hostname
atf_test_case config2_userdata_write_files
@@ -1113,6 +1114,32 @@ EOF
atf_check -o inline:"::1\t\tlocalhost\n127.0.0.1\t\tlocalhost\n" cat etc/hosts
}
+config2_userdata_mounts_head()
+{
+ atf_set "require.user" root
+}
+config2_userdata_mounts_body()
+{
+ mkdir -p media/nuageinit
+ setup_test_adduser
+ printf "{}" > media/nuageinit/meta_data.json
+ cat > media/nuageinit/user_data <<EOF
+#cloud-config
+mounts:
+ - [ /dev/ada1p1, /mnt/data, ufs, rw, 0, 2 ]
+ - device: tmpfs
+ mountpoint: /mnt/tmp
+ fstype: tmpfs
+ options: "size=256M"
+EOF
+ atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
+ atf_check -o match:"/dev/ada1p1.*/mnt/data.*ufs.*rw.*0.*2" cat etc/fstab
+ atf_check -o match:"tmpfs.*/mnt/tmp.*tmpfs.*size=256M.*0.*0" cat etc/fstab
+ test -d mnt/data || atf_fail "/mnt/data directory not created"
+ test -d mnt/tmp || atf_fail "/mnt/tmp directory not created"
+ true
+}
+
config2_userdata_fqdn_and_hostname_body()
{
mkdir -p media/nuageinit
@@ -1162,6 +1189,7 @@ atf_init_test_cases()
atf_add_test_case config2_userdata_disable_root
atf_add_test_case config2_userdata_bootcmd
atf_add_test_case config2_userdata_manage_etc_hosts
+ atf_add_test_case config2_userdata_mounts
atf_add_test_case config2_userdata_fqdn_and_hostname
atf_add_test_case config2_userdata_write_files
}