From 3f2792166aeed4baf07d351bcb12a9d196c443eb Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 26 Sep 2024 08:02:06 +0200 Subject: [PATCH 01/12] MAC: improve consistency in error handling Whenever mac_syncache_init() returns an error, ensure that *label = NULL. This simplifies the error handling by the caller. Reviewed by: rscheff MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46701 --- sys/security/mac/mac_inet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/security/mac/mac_inet.c b/sys/security/mac/mac_inet.c index 29a355071065..9770fa840f95 100644 --- a/sys/security/mac/mac_inet.c +++ b/sys/security/mac/mac_inet.c @@ -485,6 +485,7 @@ mac_syncache_init(struct label **label) MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label, *label); mac_labelzone_free(*label); + *label = NULL; } return (error); } else From 2fb778fab893b4a8a86ecfa20acf2e23bb2cdae8 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 26 Sep 2024 08:06:24 +0200 Subject: [PATCH 02/12] MAC: improve handling of listening sockets so_peerlabel can only be used when the socket is not listening. Reviewed by: markj MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46755 --- sys/kern/uipc_socket.c | 5 +++++ sys/security/mac/mac_internal.h | 1 + sys/security/mac/mac_socket.c | 19 +++++++++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index e83422e3a29f..189e8ca5b498 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -153,6 +153,7 @@ #include #include +#include #include @@ -1485,6 +1486,10 @@ solisten_proto(struct socket *so, int backlog) sbrcv_timeo = so->so_rcv.sb_timeo; sbsnd_timeo = so->so_snd.sb_timeo; +#ifdef MAC + mac_socketpeer_label_free(so->so_peerlabel); +#endif + if (!(so->so_proto->pr_flags & PR_SOCKBUF)) { sbdestroy(so, SO_SND); sbdestroy(so, SO_RCV); diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h index aa407598600a..89f74a65c803 100644 --- a/sys/security/mac/mac_internal.h +++ b/sys/security/mac/mac_internal.h @@ -242,6 +242,7 @@ struct label *mac_pipe_label_alloc(void); void mac_pipe_label_free(struct label *label); struct label *mac_socket_label_alloc(int flag); void mac_socket_label_free(struct label *label); +void mac_socketpeer_label_free(struct label *label); struct label *mac_vnode_label_alloc(void); void mac_vnode_label_free(struct label *label); diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c index e9f94404734a..b03f98bbfdb5 100644 --- a/sys/security/mac/mac_socket.c +++ b/sys/security/mac/mac_socket.c @@ -170,7 +170,7 @@ mac_socket_label_free(struct label *label) mac_labelzone_free(label); } -static void +void mac_socketpeer_label_free(struct label *label) { @@ -185,8 +185,10 @@ mac_socket_destroy(struct socket *so) if (so->so_label != NULL) { mac_socket_label_free(so->so_label); so->so_label = NULL; - mac_socketpeer_label_free(so->so_peerlabel); - so->so_peerlabel = NULL; + if (!SOLISTENING(so)) { + mac_socketpeer_label_free(so->so_peerlabel); + so->so_peerlabel = NULL; + } } } @@ -618,10 +620,15 @@ mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so, buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); intlabel = mac_socket_label_alloc(M_WAITOK); SOCK_LOCK(so); - mac_socket_copy_label(so->so_peerlabel, intlabel); + if (SOLISTENING(so)) + error = EINVAL; + else + mac_socket_copy_label(so->so_peerlabel, intlabel); SOCK_UNLOCK(so); - error = mac_socketpeer_externalize_label(intlabel, elements, buffer, - mac->m_buflen); + if (error == 0) { + error = mac_socketpeer_externalize_label(intlabel, elements, buffer, + mac->m_buflen); + } mac_socket_label_free(intlabel); if (error == 0) error = copyout(buffer, mac->m_string, strlen(buffer)+1); From 78e1b031d2e8ef0e1cbc8874891f5476dc7868bc Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 26 Sep 2024 08:10:01 +0200 Subject: [PATCH 03/12] tcp: improve MAC error handling for SYN segments Don't leak a maclabel when SYN segments are processed which results in an error due to MD5 signature handling. Tweak the #idef MAC to allow additional upcoming changes. Reviewed by: markj MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46766 --- sys/netinet/tcp_syncache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 80bf12474c1c..ed131421207d 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1372,7 +1372,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, int autoflowlabel = 0; #endif #ifdef MAC - struct label *maclabel; + struct label *maclabel = NULL; #endif struct syncache scs; struct ucred *cred; @@ -1763,10 +1763,11 @@ donenoprobe: tfo_expanded: if (cred != NULL) crfree(cred); + if (sc == NULL || sc == &scs) { #ifdef MAC - if (sc == &scs) mac_syncache_destroy(&maclabel); #endif + } return (rv); } From 99adbd1b3f3b2c198a8994c9681655978a7d9a1f Mon Sep 17 00:00:00 2001 From: Tom Jones Date: Thu, 26 Sep 2024 10:13:41 +0100 Subject: [PATCH 04/12] gpioc: Fix handling of priv data during open Fix the ordering of priv data creation with setting priv data. This handles failure better and resolves a panic when repeatedly running tools/tools/gpioevents. Explicitly initialise more fields in priv data while we are here. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46568 --- sys/dev/gpio/gpioc.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sys/dev/gpio/gpioc.c b/sys/dev/gpio/gpioc.c index 4ebf958d6974..b9d95338e211 100644 --- a/sys/dev/gpio/gpioc.c +++ b/sys/dev/gpio/gpioc.c @@ -677,19 +677,18 @@ static int gpioc_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { struct gpioc_cdevpriv *priv; - int err; + int err = 0; priv = malloc(sizeof(*priv), M_GPIOC, M_WAITOK | M_ZERO); priv->sc = dev->si_drv1; - priv->report_option = GPIO_EVENT_REPORT_DETAIL; - err = devfs_set_cdevpriv(priv, gpioc_cdevpriv_dtor); - if (err != 0) { - gpioc_cdevpriv_dtor(priv); - return (err); - } + mtx_init(&priv->mtx, "gpioc priv", NULL, MTX_DEF); knlist_init_mtx(&priv->selinfo.si_note, &priv->mtx); + priv->async = false; + priv->report_option = GPIO_EVENT_REPORT_DETAIL; + priv->sigio = NULL; + /* * Allocate a circular buffer for events. The scheme we use for summary * reporting assumes there will always be a pair of events available to @@ -701,7 +700,13 @@ gpioc_open(struct cdev *dev, int oflags, int devtype, struct thread *td) priv->events = malloc(priv->numevents * sizeof(struct gpio_event_detail), M_GPIOC, M_WAITOK | M_ZERO); - return (0); + priv->evidx_head = priv->evidx_tail = 0; + SLIST_INIT(&priv->pins); + + err = devfs_set_cdevpriv(priv, gpioc_cdevpriv_dtor); + if (err != 0) + gpioc_cdevpriv_dtor(priv); + return (err); } static int From 504981357aa36365784458cfe8d9e23097bfac7b Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Mon, 29 Jul 2024 18:40:52 +0000 Subject: [PATCH 05/12] nuageinit: Lua check and lint files Mostly white space, style, and luacheck compliance. Signed-off-by: Jose Luis Duran --- libexec/nuageinit/nuage.lua | 56 +++---- libexec/nuageinit/nuageinit | 160 ++++++++++---------- libexec/nuageinit/tests/Makefile | 10 +- libexec/nuageinit/tests/addgroup.lua | 1 + libexec/nuageinit/tests/addsshkey.lua | 3 + libexec/nuageinit/tests/adduser.lua | 1 + libexec/nuageinit/tests/dirname.lua | 7 +- libexec/nuageinit/tests/err.lua | 1 + libexec/nuageinit/tests/nuage.sh | 21 ++- libexec/nuageinit/tests/nuageinit.sh | 187 ++++++++++++------------ libexec/nuageinit/tests/sethostname.lua | 1 + libexec/nuageinit/tests/utils.sh | 18 ++- libexec/nuageinit/tests/warn.lua | 1 + libexec/nuageinit/yaml.lua | 1 + 14 files changed, 259 insertions(+), 209 deletions(-) diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua index 116ab143ccfa..d35d3725fa99 100644 --- a/libexec/nuageinit/nuage.lua +++ b/libexec/nuageinit/nuage.lua @@ -1,15 +1,17 @@ +--- -- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright(c) 2022 Baptiste Daroussin +local lfs = require("lfs") local pu = require("posix.unistd") local function warnmsg(str) - io.stderr:write(str.."\n") + io.stderr:write(str .. "\n") end local function errmsg(str) - io.stderr:write(str.."\n") + io.stderr:write(str .. "\n") os.exit(1) end @@ -28,15 +30,17 @@ local function mkdir_p(path) if lfs.attributes(path, "mode") ~= nil then return true end - local r,err = mkdir_p(dirname(path)) + local r, err = mkdir_p(dirname(path)) if not r then - return nil,err.." (creating "..path..")" + return nil, err .. " (creating " .. path .. ")" end return lfs.mkdir(path) end local function sethostname(hostname) - if hostname == nil then return end + if hostname == nil then + return + end local root = os.getenv("NUAGE_FAKE_ROOTDIR") if not root then root = "" @@ -44,12 +48,12 @@ local function sethostname(hostname) local hostnamepath = root .. "/etc/rc.conf.d/hostname" mkdir_p(dirname(hostnamepath)) - local f,err = io.open(hostnamepath, "w") + local f, err = io.open(hostnamepath, "w") if not f then - warnmsg("Impossible to open "..hostnamepath .. ":" ..err) + warnmsg("Impossible to open " .. hostnamepath .. ":" .. err) return end - f:write("hostname=\""..hostname.."\"\n") + f:write('hostname="' .. hostname .. '"\n') f:close() end @@ -62,7 +66,7 @@ local function splitlist(list) elseif type(list) == "table" then ret = list else - warnmsg("Invalid type ".. type(list) ..", expecting table or string") + warnmsg("Invalid type " .. type(list) .. ", expecting table or string") end return ret end @@ -77,7 +81,7 @@ local function adduser(pwd) if root then cmd = cmd .. "-R " .. root .. " " end - local f = io.popen(cmd .. " usershow " ..pwd.name .. " -7 2>/dev/null") + local f = io.popen(cmd .. " usershow " .. pwd.name .. " -7 2> /dev/null") local pwdstr = f:read("*a") f:close() if pwdstr:len() ~= 0 then @@ -89,10 +93,10 @@ local function adduser(pwd) if not pwd.homedir then pwd.homedir = "/home/" .. pwd.name end - local extraargs="" + local extraargs = "" if pwd.groups then local list = splitlist(pwd.groups) - extraargs = " -G ".. table.concat(list, ',') + extraargs = " -G " .. table.concat(list, ",") end -- pw will automatically create a group named after the username -- do not add a -g option in this case @@ -108,23 +112,23 @@ local function adduser(pwd) local precmd = "" local postcmd = "" if pwd.passwd then - precmd = "echo "..pwd.passwd .. "| " + precmd = "echo " .. pwd.passwd .. "| " postcmd = " -H 0 " elseif pwd.plain_text_passwd then - precmd = "echo "..pwd.plain_text_passwd .. "| " + precmd = "echo " .. pwd.plain_text_passwd .. "| " postcmd = " -h 0 " end cmd = precmd .. "pw " if root then cmd = cmd .. "-R " .. root .. " " end - cmd = cmd .. "useradd -n ".. pwd.name .. " -M 0755 -w none " - cmd = cmd .. extraargs .. " -c '".. pwd.gecos - cmd = cmd .. "' -d '" .. pwd.homedir .. "' -s "..pwd.shell .. postcmd + cmd = cmd .. "useradd -n " .. pwd.name .. " -M 0755 -w none " + cmd = cmd .. extraargs .. " -c '" .. pwd.gecos + cmd = cmd .. "' -d '" .. pwd.homedir .. "' -s " .. pwd.shell .. postcmd local r = os.execute(cmd) if not r then - warnmsg("nuageinit: fail to add user "..pwd.name); + warnmsg("nuageinit: fail to add user " .. pwd.name) warnmsg(cmd) return nil end @@ -149,7 +153,7 @@ local function addgroup(grp) if root then cmd = cmd .. "-R " .. root .. " " end - local f = io.popen(cmd .. " groupshow " ..grp.name .. " 2>/dev/null") + local f = io.popen(cmd .. " groupshow " .. grp.name .. " 2> /dev/null") local grpstr = f:read("*a") f:close() if grpstr:len() ~= 0 then @@ -158,16 +162,16 @@ local function addgroup(grp) local extraargs = "" if grp.members then local list = splitlist(grp.members) - extraargs = " -M " .. table.concat(list, ',') + extraargs = " -M " .. table.concat(list, ",") end cmd = "pw " if root then cmd = cmd .. "-R " .. root .. " " end - cmd = cmd .. "groupadd -n ".. grp.name .. extraargs + cmd = cmd .. "groupadd -n " .. grp.name .. extraargs local r = os.execute(cmd) if not r then - warnmsg("nuageinit: fail to add group ".. grp.name); + warnmsg("nuageinit: fail to add group " .. grp.name) warnmsg(cmd) return false end @@ -196,7 +200,7 @@ local function addsshkey(homedir, key) local f = io.open(ak_path, "a") if not f then - warnmsg("nuageinit: impossible to open "..ak_path) + warnmsg("nuageinit: impossible to open " .. ak_path) return end f:write(key .. "\n") @@ -214,12 +218,12 @@ end local n = { warn = warnmsg, err = errmsg, + dirname = dirname, + mkdir_p = mkdir_p, sethostname = sethostname, adduser = adduser, addgroup = addgroup, - addsshkey = addsshkey, - dirname = dirname, - mkdir_p = mkdir_p, + addsshkey = addsshkey } return n diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit index 622e294bb531..50d77dfef9f5 100755 --- a/libexec/nuageinit/nuageinit +++ b/libexec/nuageinit/nuageinit @@ -1,18 +1,18 @@ #!/usr/libexec/flua - +--- -- SPDX-License-Identifier: BSD-2-Clause-FreeBSD -- -- Copyright(c) 2022 Baptiste Daroussin local nuage = require("nuage") +local ucl = require("ucl") local yaml = require("yaml") if #arg ~= 2 then - nuage.err("Usage ".. arg[0] .." [config-2|nocloud]") + nuage.err("Usage " .. arg[0] .. " [config-2|nocloud]") end local path = arg[1] local citype = arg[2] -local ucl = require("ucl") local default_user = { name = "freebsd", @@ -30,9 +30,9 @@ end local function open_config(name) nuage.mkdir_p(root .. "/etc/rc.conf.d") - local f,err = io.open(root .. "/etc/rc.conf.d/" .. name, "w") + local f, err = io.open(root .. "/etc/rc.conf.d/" .. name, "w") if not f then - nuage.err("nuageinit: unable to open "..name.." config: " .. err) + nuage.err("nuageinit: unable to open " .. name .. " config: " .. err) end return f end @@ -40,17 +40,17 @@ end local function get_ifaces() local parser = ucl.parser() -- grab ifaces - local ns = io.popen('netstat -i --libxo json') + local ns = io.popen("netstat -i --libxo json") local netres = ns:read("*a") ns:close() - local res,err = parser:parse_string(netres) + local res, err = parser:parse_string(netres) if not res then nuage.warn("Error parsing netstat -i --libxo json outout: " .. err) return nil end local ifaces = parser:get_object() local myifaces = {} - for _,iface in pairs(ifaces["statistics"]["interface"]) do + for _, iface in pairs(ifaces["statistics"]["interface"]) do if iface["network"]:match("") then local s = iface["address"] myifaces[s:lower()] = iface["name"] @@ -67,7 +67,7 @@ local function config2_network(p) return end f:close() - local res,err = parser:parse_file(p .. "/network_data.json") + local res, err = parser:parse_file(p .. "/network_data.json") if not res then nuage.warn("nuageinit: error parsing network_data.json: " .. err) return @@ -80,7 +80,7 @@ local function config2_network(p) return end local mylinks = {} - for _,v in pairs(obj["links"]) do + for _, v in pairs(obj["links"]) do local s = v["ethernet_mac_address"]:lower() mylinks[v["id"]] = ifaces[s] end @@ -91,66 +91,72 @@ local function config2_network(p) local ipv6 = {} local ipv6_routes = {} local ipv4 = {} - for _,v in pairs(obj["networks"]) do + for _, v in pairs(obj["networks"]) do local interface = mylinks[v["link"]] if v["type"] == "ipv4_dhcp" then - network:write("ifconfig_"..interface.."=\"DHCP\"\n") + network:write("ifconfig_" .. interface .. '="DHCP"\n') end if v["type"] == "ipv4" then - network:write("ifconfig_"..interface.."=\"inet "..v["ip_address"].." netmask " .. v["netmask"] .. "\"\n") + network:write( + "ifconfig_" .. interface .. '="inet ' .. v["ip_address"] .. " netmask " .. v["netmask"] .. '"\n' + ) if v["gateway"] then - routing:write("defaultrouter=\""..v["gateway"].."\"\n") + routing:write('defaultrouter="' .. v["gateway"] .. '"\n') end if v["routes"] then - for i,r in ipairs(v["routes"]) do + for i, r in ipairs(v["routes"]) do local rname = "cloudinit" .. i .. "_" .. interface - if v["gateway"] and v["gateway"] == r["gateway"] then goto next end - if r["network"] == "0.0.0.0" then - routing:write("defaultrouter=\""..r["gateway"].."\"\n") + if v["gateway"] and v["gateway"] == r["gateway"] then goto next end - routing:write("route_".. rname .. "=\"-net ".. r["network"] .. " ") - routing:write(r["gateway"] .. " " .. r["netmask"] .. "\"\n") + if r["network"] == "0.0.0.0" then + routing:write('defaultrouter="' .. r["gateway"] .. '"\n') + goto next + end + routing:write("route_" .. rname .. '="-net ' .. r["network"] .. " ") + routing:write(r["gateway"] .. " " .. r["netmask"] .. '"\n') ipv4[#ipv4 + 1] = rname ::next:: end end end if v["type"] == "ipv6" then - ipv6[#ipv6+1] = interface - ipv6_routes[#ipv6_routes+1] = interface - network:write("ifconfig_"..interface.."_ipv6=\"inet6 "..v["ip_address"].."\"\n") + ipv6[#ipv6 + 1] = interface + ipv6_routes[#ipv6_routes + 1] = interface + network:write("ifconfig_" .. interface .. '_ipv6="inet6 ' .. v["ip_address"] .. '"\n') if v["gateway"] then - routing:write("ipv6_defaultrouter=\""..v["gateway"].."\"\n") - routing:write("ipv6_route_"..interface.."=\""..v["gateway"]) - routing:write(" -prefixlen 128 -interface "..interface.."\"\n") + routing:write('ipv6_defaultrouter="' .. v["gateway"] .. '"\n') + routing:write("ipv6_route_" .. interface .. '="' .. v["gateway"]) + routing:write(" -prefixlen 128 -interface " .. interface .. '"\n') end -- TODO compute the prefixlen for the routes --if v["routes"] then - -- for i,r in ipairs(v["routes"]) do + -- for i, r in ipairs(v["routes"]) do -- local rname = "cloudinit" .. i .. "_" .. mylinks[v["link"]] -- -- skip all the routes which are already covered by the default gateway, some provider -- -- still list plenty of them. - -- if v["gateway"] == r["gateway"] then goto next end - -- routing:write("ipv6_route_" .. rname .. "\"\n") - -- ipv6_routes[#ipv6_routes+1] = rname + -- if v["gateway"] == r["gateway"] then + -- goto next + -- end + -- routing:write("ipv6_route_" .. rname .. '"\n') + -- ipv6_routes[#ipv6_routes + 1] = rname -- ::next:: -- end --end end end if #ipv4 > 0 then - routing:write("static_routes=\"") - routing:write(table.concat(ipv4, " ") .. "\"\n") + routing:write('static_routes="') + routing:write(table.concat(ipv4, " ") .. '"\n') end if #ipv6 > 0 then - network:write("ipv6_network_interfaces=\"") - network:write(table.concat(ipv6, " ") .. "\"\n") - network:write("ipv6_default_interface=\""..ipv6[1].."\"\n") + network:write('ipv6_network_interfaces="') + network:write(table.concat(ipv6, " ") .. '"\n') + network:write('ipv6_default_interface="' .. ipv6[1] .. '"\n') end if #ipv6_routes > 0 then - routing:write("ipv6_static_routes=\"") - routing:write(table.concat(ipv6, " ") .. "\"\n") + routing:write('ipv6_static_routes="') + routing:write(table.concat(ipv6, " ") .. '"\n') end network:close() routing:close() @@ -158,7 +164,7 @@ end if citype == "config-2" then local parser = ucl.parser() - local res,err = parser:parse_file(path..'/meta_data.json') + local res, err = parser:parse_file(path .. "/meta_data.json") if not res then nuage.err("nuageinit: error parsing config-2: meta_data.json: " .. err) @@ -175,32 +181,32 @@ if citype == "config-2" then -- network config2_network(path) elseif citype == "nocloud" then - local f,err = io.open(path.."/meta-data") + local f, err = io.open(path .. "/meta-data") if err then - nuage.err("nuageinit: error parsing nocloud meta-data: ".. err) + nuage.err("nuageinit: error parsing nocloud meta-data: " .. err) end local obj = yaml.eval(f:read("*a")) f:close() if not obj then nuage.err("nuageinit: error parsing nocloud meta-data") end - local hostname = obj['local-hostname'] + local hostname = obj["local-hostname"] if not hostname then - hostname = obj['hostname'] + hostname = obj["hostname"] end if hostname then nuage.sethostname(hostname) end else - nuage.err("Unknown cloud init type: ".. citype) + nuage.err("Unknown cloud init type: " .. citype) end -- deal with user-data local ud = nil local f = nil -userdatas = { "user-data", "user_data" } -for _,v in pairs(userdatas) do - f = io.open(path..'/' .. v, "r") +userdatas = {"user-data", "user_data"} +for _, v in pairs(userdatas) do + f = io.open(path .. "/" .. v, "r") if f then ud = v break @@ -209,33 +215,33 @@ end if not f then os.exit(0) end -local line = f:read('*l') +local line = f:read("*l") f:close() if line == "#cloud-config" then - f = io.open(path.."/" .. ud) + f = io.open(path .. "/" .. ud) local obj = yaml.eval(f:read("*a")) f:close() if not obj then nuage.err("nuageinit: error parsing cloud-config file: " .. ud) end if obj.groups then - for n,g in pairs(obj.groups) do + for n, g in pairs(obj.groups) do if (type(g) == "string") then local r = nuage.addgroup({name = g}) if not r then - nuage.warn("nuageinit: failed to add group: ".. g) + nuage.warn("nuageinit: failed to add group: " .. g) end elseif type(g) == "table" then - for k,v in pairs(g) do + for k, v in pairs(g) do nuage.addgroup({name = k, members = v}) end else - nuage.warn("nuageinit: invalid type : "..type(g).." for users entry number "..n); + nuage.warn("nuageinit: invalid type: " .. type(g) .. " for users entry number " .. n) end end end if obj.users then - for n,u in pairs(obj.users) do + for n, u in pairs(obj.users) do if type(u) == "string" then if u == "default" then nuage.adduser(default_user) @@ -249,12 +255,12 @@ if line == "#cloud-config" then end local homedir = nuage.adduser(u) if u.ssh_authorized_keys then - for _,v in ipairs(u.ssh_authorized_keys) do + for _, v in ipairs(u.ssh_authorized_keys) do nuage.addsshkey(homedir, v) end end else - nuage.warn("nuageinit: invalid type : "..type(u).." for users entry number "..n); + nuage.warn("nuageinit: invalid type : " .. type(u) .. " for users entry number " .. n) end ::unext:: end @@ -264,7 +270,7 @@ if line == "#cloud-config" then end if obj.ssh_authorized_keys then local homedir = nuage.adduser(default_user) - for _,k in ipairs(obj.ssh_authorized_keys) do + for _, k in ipairs(obj.ssh_authorized_keys) do nuage.addsshkey(homedir, k) end end @@ -273,48 +279,52 @@ if line == "#cloud-config" then nuage.mkdir_p(root .. "/etc/rc.conf.d") local network = open_config("network") local routing = open_config("routing") - local ipv6={} - for _,v in pairs(obj.network.ethernets) do - if not v.match then goto next end - if not v.match.macaddress then goto next end + local ipv6 = {} + for _, v in pairs(obj.network.ethernets) do + if not v.match then + goto next + end + if not v.match.macaddress then + goto next + end if not ifaces[v.match.macaddress] then - nuage.warn("nuageinit: not interface matching: "..v.match.macaddress) + nuage.warn("nuageinit: not interface matching: " .. v.match.macaddress) goto next end local interface = ifaces[v.match.macaddress] if v.dhcp4 then - network:write("ifconfig_"..interface.."=\"DHCP\"\n") + network:write("ifconfig_" .. interface .. '="DHCP"\n') elseif v.addresses then - for _,a in pairs(v.addresses) do + for _, a in pairs(v.addresses) do if a:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)") then - network:write("ifconfig_"..interface.."=\"inet "..a.."\"\n") + network:write("ifconfig_" .. interface .. '="inet ' .. a .. '"\n') else - network:write("ifconfig_"..interface.."_ipv6=\"inet6 "..a.."\"\n") - ipv6[#ipv6 +1] = interface + network:write("ifconfig_" .. interface .. '_ipv6="inet6 ' .. a .. '"\n') + ipv6[#ipv6 + 1] = interface end end end if v.gateway4 then - routing:write("defaultrouter=\""..v.gateway4.."\"\n") + routing:write('defaultrouter="' .. v.gateway4 .. '"\n') end if v.gateway6 then - routing:write("ipv6_defaultrouter=\""..v.gateway6.."\"\n") - routing:write("ipv6_route_"..interface.."=\""..v.gateway6) - routing:write(" -prefixlen 128 -interface "..interface.."\"\n") + routing:write('ipv6_defaultrouter="' .. v.gateway6 .. '"\n') + routing:write("ipv6_route_" .. interface .. '="' .. v.gateway6) + routing:write(" -prefixlen 128 -interface " .. interface .. '"\n') end ::next:: end if #ipv6 > 0 then - network:write("ipv6_network_interfaces=\"") - network:write(table.concat(ipv6, " ") .. "\"\n") - network:write("ipv6_default_interface=\""..ipv6[1].."\"\n") + network:write('ipv6_network_interfaces="') + network:write(table.concat(ipv6, " ") .. '"\n') + network:write('ipv6_default_interface="' .. ipv6[1] .. '"\n') end network:close() routing:close() end else - local res,err = os.execute(path..'/' .. ud) + local res, err = os.execute(path .. "/" .. ud) if not res then - nuage.err("nuageinit: error executing user-data script: ".. err) + nuage.err("nuageinit: error executing user-data script: " .. err) end end diff --git a/libexec/nuageinit/tests/Makefile b/libexec/nuageinit/tests/Makefile index d5b3bd9dcc82..ccb81c090445 100644 --- a/libexec/nuageinit/tests/Makefile +++ b/libexec/nuageinit/tests/Makefile @@ -2,12 +2,12 @@ PACKAGE= tests ATF_TESTS_SH= nuage utils nuageinit -${PACKAGE}FILES+= warn.lua -${PACKAGE}FILES+= err.lua -${PACKAGE}FILES+= dirname.lua -${PACKAGE}FILES+= sethostname.lua +${PACKAGE}FILES+= addgroup.lua ${PACKAGE}FILES+= addsshkey.lua ${PACKAGE}FILES+= adduser.lua -${PACKAGE}FILES+= addgroup.lua +${PACKAGE}FILES+= dirname.lua +${PACKAGE}FILES+= err.lua +${PACKAGE}FILES+= sethostname.lua +${PACKAGE}FILES+= warn.lua .include diff --git a/libexec/nuageinit/tests/addgroup.lua b/libexec/nuageinit/tests/addgroup.lua index 60a0d8346793..a36a5e24c7b3 100644 --- a/libexec/nuageinit/tests/addgroup.lua +++ b/libexec/nuageinit/tests/addgroup.lua @@ -1,6 +1,7 @@ #!/usr/libexec/flua local n = require("nuage") + if n.addgroup() then n.err("addgroup should not accept empty value") end diff --git a/libexec/nuageinit/tests/addsshkey.lua b/libexec/nuageinit/tests/addsshkey.lua index 3aa5f7619ec2..47e102c162a9 100644 --- a/libexec/nuageinit/tests/addsshkey.lua +++ b/libexec/nuageinit/tests/addsshkey.lua @@ -1,2 +1,5 @@ +#!/usr/libexec/flua + local n = require("nuage") + n.addsshkey(".", "mykey") diff --git a/libexec/nuageinit/tests/adduser.lua b/libexec/nuageinit/tests/adduser.lua index 9366d2abd0f4..cef6be0c0e0c 100644 --- a/libexec/nuageinit/tests/adduser.lua +++ b/libexec/nuageinit/tests/adduser.lua @@ -1,6 +1,7 @@ #!/usr/libexec/flua local n = require("nuage") + if n.adduser() then n.err("adduser should not accept empty value") end diff --git a/libexec/nuageinit/tests/dirname.lua b/libexec/nuageinit/tests/dirname.lua index d1268e48575c..7e3a2c835502 100644 --- a/libexec/nuageinit/tests/dirname.lua +++ b/libexec/nuageinit/tests/dirname.lua @@ -1,8 +1,11 @@ +#!/usr/libexec/flua + local n = require("nuage") + print(n.dirname("/my/path/path1")) if n.dirname("path") then - nuage.err("Expecting nil for n.dirname(\"path\")") + n.err('Expecting nil for n.dirname("path")') end if n.dirname() then - nuage.err("Expecting nil for n.dirname") + n.err("Expecting nil for n.dirname") end diff --git a/libexec/nuageinit/tests/err.lua b/libexec/nuageinit/tests/err.lua index c62fa1098f09..567d4f2df66e 100644 --- a/libexec/nuageinit/tests/err.lua +++ b/libexec/nuageinit/tests/err.lua @@ -1,4 +1,5 @@ #!/usr/libexec/flua local n = require("nuage") + n.err("plop") diff --git a/libexec/nuageinit/tests/nuage.sh b/libexec/nuageinit/tests/nuage.sh index 29842bff3d6b..4e2353176b16 100644 --- a/libexec/nuageinit/tests/nuage.sh +++ b/libexec/nuageinit/tests/nuage.sh @@ -1,9 +1,16 @@ +#- +# Copyright (c) 2022 Baptiste Daroussin +# +# SPDX-License-Identifier: BSD-2-Clause +# + atf_test_case sethostname atf_test_case addsshkey atf_test_case adduser atf_test_case addgroup -sethostname_body() { +sethostname_body() +{ export NUAGE_FAKE_ROOTDIR="$(pwd)" atf_check /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua if [ ! -f etc/rc.conf.d/hostname ]; then @@ -12,7 +19,8 @@ sethostname_body() { atf_check -o inline:"hostname=\"myhostname\"\n" cat etc/rc.conf.d/hostname } -addsshkey_body() { +addsshkey_body() +{ atf_check /usr/libexec/flua $(atf_get_srcdir)/addsshkey.lua if [ ! -f .ssh/authorized_keys ]; then atf_fail "ssh key not added" @@ -24,7 +32,8 @@ addsshkey_body() { atf_check -o inline:"mykey\nmykey\n" cat .ssh/authorized_keys } -adduser_body() { +adduser_body() +{ export NUAGE_FAKE_ROOTDIR="$(pwd)" if [ $(id -u) -ne 0 ]; then atf_skip "root required" @@ -38,7 +47,8 @@ adduser_body() { atf_check -o inline:"impossible_username::1001:1001::0:0:impossible_username User:/home/impossible_username:/bin/sh\n" grep impossible_username etc/master.passwd } -addgroup_body() { +addgroup_body() +{ export NUAGE_FAKE_ROOTDIR="$(pwd)" mkdir etc printf "wheel:*:0:root\n" > etc/group @@ -46,7 +56,8 @@ addgroup_body() { atf_check -o inline:"impossible_groupname:*:1001:\n" grep impossible_groupname etc/group } -atf_init_test_cases() { +atf_init_test_cases() +{ atf_add_test_case sethostname atf_add_test_case addsshkey atf_add_test_case adduser diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh index b5078e256853..64ac066fefbf 100644 --- a/libexec/nuageinit/tests/nuageinit.sh +++ b/libexec/nuageinit/tests/nuageinit.sh @@ -1,8 +1,13 @@ +#- +# Copyright (c) 2022 Baptiste Daroussin +# +# SPDX-License-Identifier: BSD-2-Clause +# + atf_test_case args atf_test_case nocloud atf_test_case nocloud_userdata_script atf_test_case nocloud_user_data_script -atf_test_case nocloud_userdata_cloudconfig atf_test_case nocloud_userdata_cloudconfig_users atf_test_case nocloud_network atf_test_case config2 @@ -12,7 +17,6 @@ atf_test_case config2_pubkeys_meta_data atf_test_case config2_network atf_test_case config2_network_static_v4 - args_body() { atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit [config-2|nocloud]\n" /usr/libexec/nuageinit @@ -43,8 +47,8 @@ nocloud_userdata_script_body() here=$(pwd) mkdir -p media/nuageinit printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data - printf "#!/bin/sh\necho "yeah"\n" > ${here}/media/nuageinit/user-data - chmod 755 ${here}/media/nuageinit/user-data + printf "#!/bin/sh\necho yeah\n" > ${here}/media/nuageinit/user-data + chmod 755 ${here}/media/nuageinit/user-data atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit ${here}/media/nuageinit nocloud } @@ -53,8 +57,8 @@ nocloud_user_data_script_body() here=$(pwd) mkdir -p media/nuageinit printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data - printf "#!/bin/sh\necho "yeah"\n" > ${here}/media/nuageinit/user_data - chmod 755 ${here}/media/nuageinit/user_data + printf "#!/bin/sh\necho yeah\n" > ${here}/media/nuageinit/user_data + chmod 755 ${here}/media/nuageinit/user_data atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit ${here}/media/nuageinit nocloud } @@ -68,16 +72,16 @@ nocloud_userdata_cloudconfig_users_body() mkdir -p media/nuageinit printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data mkdir -p etc - cat > etc/master.passwd < etc/master.passwd << EOF root:*:0:0::0:0:Charlie &:/root:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/csh EOF pwd_mkdb -d etc ${here}/etc/master.passwd - cat > etc/group < etc/group << EOF wheel:*:0:root users:*:1: EOF - cat > media/nuageinit/user-data < media/nuageinit/user-data << EOF #cloud-config groups: - admingroup: [root,sys] @@ -115,12 +119,12 @@ nocloud_network_body() here=$(pwd) mkdir -p media/nuageinit mkdir -p etc - cat > etc/master.passwd < etc/master.passwd << EOF root:*:0:0::0:0:Charlie &:/root:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/csh EOF pwd_mkdb -d etc ${here}/etc/master.passwd - cat > etc/group < etc/group << EOF wheel:*:0:root users:*:1: EOF @@ -135,16 +139,15 @@ EOF myiface=$1 myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }') printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data - cat > media/nuageinit/user-data < media/nuageinit/user-data << EOF #cloud-config -# network: version: 2 ethernets: # opaque ID for physical interfaces, only referred to by other stanzas id0: match: - macaddress: '${myaddr}' + macaddress: "$myaddr" addresses: - 192.168.14.2/24 - 2001:1::1/64 @@ -153,13 +156,13 @@ network: EOF export NUAGE_FAKE_ROOTDIR=$(pwd) atf_check /usr/libexec/nuageinit ${here}/media/nuageinit nocloud - cat > network < network << EOF ifconfig_${myiface}="inet 192.168.14.2/24" ifconfig_${myiface}_ipv6="inet6 2001:1::1/64" ipv6_network_interfaces="${myiface}" ipv6_default_interface="${myiface}" EOF - cat > routing < routing << EOF defaultrouter="192.168.14.1" ipv6_defaultrouter="2001:1::2" ipv6_route_${myiface}="2001:1::2 -prefixlen 128 -interface ${myiface}" @@ -176,7 +179,7 @@ config2_body() atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 cat > media/nuageinit/meta_data.json << EOF { - "hostname": "cloudimg", + "hostname": "cloudimg" } EOF export NUAGE_FAKE_ROOTDIR=$(pwd) @@ -195,17 +198,16 @@ config2_pubkeys_body() touch media/nuageinit/meta_data.json cat > media/nuageinit/user-data << EOF #cloud-config - ssh_authorized_keys: - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova" EOF mkdir -p etc - cat > etc/master.passwd < etc/master.passwd << EOF root:*:0:0::0:0:Charlie &:/root:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/csh EOF pwd_mkdb -d etc ${here}/etc/master.passwd - cat > etc/group < etc/group << EOF wheel:*:0:root users:*:1: EOF @@ -225,17 +227,16 @@ config2_pubkeys_user_data_body() touch media/nuageinit/meta_data.json cat > media/nuageinit/user_data << EOF #cloud-config - ssh_authorized_keys: - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova" EOF mkdir -p etc - cat > etc/master.passwd < etc/master.passwd << EOF root:*:0:0::0:0:Charlie &:/root:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/csh EOF pwd_mkdb -d etc ${here}/etc/master.passwd - cat > etc/group < etc/group << EOF wheel:*:0:root users:*:1: EOF @@ -251,37 +252,37 @@ config2_pubkeys_meta_data_body() atf_skip "root required" fi mkdir -p media/nuageinit - cat > media/nuageinit/meta_data.json < media/nuageinit/meta_data.json << EOF { - "uuid": "uuid_for_this_instance", - "admin_pass": "a_generated_password", - "public_keys": { - "tdb": "ssh-ed25519 my_key_id tdb@host" - }, - "keys": [ - { - "name": "tdb", - "type": "ssh", - "data": "ssh-ed25519 my_key_id tdb@host" - } - ], - "hostname": "freebsd-14-test.novalocal", - "name": "freebsd-14-test", - "launch_index": 0, - "availability_zone": "nova", - "random_seed": "long_random_seed", - "project_id": "my_project_id", - "devices": [], - "dedicated_cpus": [] + "uuid": "uuid_for_this_instance", + "admin_pass": "a_generated_password", + "public_keys": { + "tdb": "ssh-ed25519 my_key_id tdb@host" + }, + "keys": [ + { + "name": "tdb", + "type": "ssh", + "data": "ssh-ed25519 my_key_id tdb@host" + } + ], + "hostname": "freebsd-14-test.novalocal", + "name": "freebsd-14-test", + "launch_index": 0, + "availability_zone": "nova", + "random_seed": "long_random_seed", + "project_id": "my_project_id", + "devices": [], + "dedicated_cpus": [] } EOF mkdir -p etc - cat > etc/master.passwd < etc/master.passwd << EOF root:*:0:0::0:0:Charlie &:/root:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/csh EOF pwd_mkdb -d etc ${here}/etc/master.passwd - cat > etc/group < etc/group << EOF wheel:*:0:root users:*:1: EOF @@ -289,7 +290,8 @@ EOF atf_check -o inline:"ssh-ed25519 my_key_id tdb@host\n" cat home/freebsd/.ssh/authorized_keys } -config2_network_body() { +config2_network_body() +{ here=$(pwd) mkdir -p media/nuageinit printf "{}" > media/nuageinit/meta_data.json @@ -300,13 +302,13 @@ config2_network_body() { set -- $mynetworks myiface=$1 myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }') -cat > media/nuageinit/network_data.json < media/nuageinit/network_data.json << EOF { "links": [ { "ethernet_mac_address": "$myaddr", "id": "iface0", - "mtu": null, + "mtu": null } ], "networks": [ @@ -315,39 +317,39 @@ cat > media/nuageinit/network_data.json < network < network << EOF ifconfig_${myiface}="DHCP" ifconfig_${myiface}_ipv6="inet6 2001:cdba::3257:9652/24" ipv6_network_interfaces="${myiface}" ipv6_default_interface="${myiface}" EOF - cat > routing < routing << EOF ipv6_defaultrouter="fd00::1" ipv6_route_${myiface}="fd00::1 -prefixlen 128 -interface ${myiface}" ipv6_static_routes="${myiface}" @@ -356,7 +358,8 @@ EOF atf_check -o file:routing cat ${here}/etc/rc.conf.d/routing } -config2_network_static_v4_body() { +config2_network_static_v4_body() +{ here=$(pwd) mkdir -p media/nuageinit printf "{}" > media/nuageinit/meta_data.json @@ -367,45 +370,45 @@ config2_network_static_v4_body() { set -- $mynetworks myiface=$1 myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }') -cat > media/nuageinit/network_data.json < media/nuageinit/network_data.json << EOF { "links": [ { "ethernet_mac_address": "$myaddr", "id": "iface0", - "mtu": null, + "mtu": null } ], "networks": [ { "id": "network0", "link": "iface0", - "type": "ipv4" + "type": "ipv4", "ip_address": "10.184.0.244", "netmask": "255.255.240.0", "routes": [ - { - "network": "10.0.0.0", - "netmask": "255.0.0.0", - "gateway": "11.0.0.1" - }, - { - "network": "0.0.0.0", - "netmask": "0.0.0.0", - "gateway": "23.253.157.1" - } - ] - } -] + { + "network": "10.0.0.0", + "netmask": "255.0.0.0", + "gateway": "11.0.0.1" + }, + { + "network": "0.0.0.0", + "netmask": "0.0.0.0", + "gateway": "23.253.157.1" + } + ] + } + ] } EOF export NUAGE_FAKE_ROOTDIR=$(pwd) atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 - cat > network < network << EOF ifconfig_${myiface}="inet 10.184.0.244 netmask 255.255.240.0" EOF - cat > routing < routing << EOF route_cloudinit1_${myiface}="-net 10.0.0.0 11.0.0.1 255.0.0.0" defaultrouter="23.253.157.1" static_routes="cloudinit1_${myiface}" diff --git a/libexec/nuageinit/tests/sethostname.lua b/libexec/nuageinit/tests/sethostname.lua index 01434403934b..47632497b545 100644 --- a/libexec/nuageinit/tests/sethostname.lua +++ b/libexec/nuageinit/tests/sethostname.lua @@ -1,4 +1,5 @@ #!/usr/libexec/flua local n = require("nuage") + n.sethostname("myhostname") diff --git a/libexec/nuageinit/tests/utils.sh b/libexec/nuageinit/tests/utils.sh index 192ccfb565cb..c3b5b8212938 100644 --- a/libexec/nuageinit/tests/utils.sh +++ b/libexec/nuageinit/tests/utils.sh @@ -1,20 +1,30 @@ +#- +# Copyright (c) 2022 Baptiste Daroussin +# +# SPDX-License-Identifier: BSD-2-Clause +# + atf_test_case warn atf_test_case err atf_test_case dirname -warn_body() { +warn_body() +{ atf_check -e "inline:plop\n" -s exit:0 /usr/libexec/flua $(atf_get_srcdir)/warn.lua } -err_body() { +err_body() +{ atf_check -e "inline:plop\n" -s exit:1 /usr/libexec/flua $(atf_get_srcdir)/err.lua } -dirname_body() { +dirname_body() +{ atf_check -o "inline:/my/path/\n" -s exit:0 /usr/libexec/flua $(atf_get_srcdir)/dirname.lua } -atf_init_test_cases() { +atf_init_test_cases() +{ atf_add_test_case warn atf_add_test_case err atf_add_test_case dirname diff --git a/libexec/nuageinit/tests/warn.lua b/libexec/nuageinit/tests/warn.lua index 8575ae92c071..ce2b63a8dbf0 100644 --- a/libexec/nuageinit/tests/warn.lua +++ b/libexec/nuageinit/tests/warn.lua @@ -1,4 +1,5 @@ #!/usr/libexec/flua local n = require("nuage") + n.warn("plop") diff --git a/libexec/nuageinit/yaml.lua b/libexec/nuageinit/yaml.lua index 8ab17b15eed7..2cd50c29a469 100644 --- a/libexec/nuageinit/yaml.lua +++ b/libexec/nuageinit/yaml.lua @@ -1,3 +1,4 @@ +--- -- SPDX-License-Identifier: MIT -- -- Copyright (c) 2017 Dominic Letz dominicletz@exosite.com From d71e2c037c942dbe2a9fd2630d5cf155dd1bf7db Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Fri, 26 Jul 2024 01:59:36 +0000 Subject: [PATCH 06/12] nuageinit: Silence an fstyp(8) warning Silence a warning emitted by fread(3) in fstyp(8)'s read_buf(), when detecting the file system type of the cloud-init device: % fstyp /dev/iso9660/cidata fstyp: fread: Invalid argument cd9660 Also rephrase slightly a comment while here. Signed-off-by: Jose Luis Duran --- libexec/rc/rc.d/nuageinit | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libexec/rc/rc.d/nuageinit b/libexec/rc/rc.d/nuageinit index 8da0b1aed741..a44761ea1d9e 100755 --- a/libexec/rc/rc.d/nuageinit +++ b/libexec/rc/rc.d/nuageinit @@ -18,8 +18,8 @@ nuageinit_start() { local citype # detect cloud init provider - # according to the specification of the config drive - # it either formatted in vfat or iso9660 and labeled + # according to the specification, the config drive + # is either formatted in vfat or iso9660 and labeled # config-2 for f in iso9660 msdosfs; do drive="/dev/$f/[cC][oO][nN][fF][iI][gG]-2" @@ -39,7 +39,7 @@ nuageinit_start() err 1 "Impossible to find a cloud init provider" fi mkdir -p /media/nuageinit - fs=$(fstyp $drive) + fs=$(fstyp $drive 2> /dev/null) mount -t $fs $drive /media/nuageinit # according to the specification, the content is either # in the openstack or ec2 directory From 9b2d92addc31ba6f5696c85d184a45d43e9073dc Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Tue, 30 Jul 2024 00:37:10 +0000 Subject: [PATCH 07/12] nuageinit: Replace os.execute with Lua libraries Prefer posix.sys.stat's chmod() to os.execute(). While here, change the name of the locals to be more descriptive. Signed-off-by: Jose Luis Duran --- libexec/nuageinit/nuage.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua index d35d3725fa99..1f035036f802 100644 --- a/libexec/nuageinit/nuage.lua +++ b/libexec/nuageinit/nuage.lua @@ -3,8 +3,9 @@ -- -- Copyright(c) 2022 Baptiste Daroussin +local unistd = require("posix.unistd") +local sys_stat = require("posix.sys.stat") local lfs = require("lfs") -local pu = require("posix.unistd") local function warnmsg(str) io.stderr:write(str .. "\n") @@ -206,12 +207,12 @@ local function addsshkey(homedir, key) f:write(key .. "\n") f:close() if chownak then - os.execute("chmod 0600 " .. ak_path) - pu.chown(ak_path, dirattrs.uid, dirattrs.gid) + sys_stat.chmod(ak_path, 384) + unistd.chown(ak_path, dirattrs.uid, dirattrs.gid) end if chowndotssh then - os.execute("chmod 0700 " .. dotssh_path) - pu.chown(dotssh_path, dirattrs.uid, dirattrs.gid) + sys_stat.chmod(dotssh_path, 448) + unistd.chown(dotssh_path, dirattrs.uid, dirattrs.gid) end end From 945632ca76117029e7bd1f46d17ccb378973daf7 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Tue, 30 Jul 2024 01:18:11 +0000 Subject: [PATCH 08/12] nuageinit: Standardize warning/error messages Standardize the utilities from nuage.lua, to return nil on failure, plus an error message as a second result, and some value different from nil on success. Make warnmsg() and errmsg() append "nuageinit: " by default. Pass an optional second parameter as false to avoid printing this tag. Signed-off-by: Jose Luis Duran --- libexec/nuageinit/nuage.lua | 21 ++++++++++++++------- libexec/nuageinit/nuageinit | 26 +++++++++++++------------- libexec/nuageinit/tests/nuage.sh | 4 ++-- libexec/nuageinit/tests/nuageinit.sh | 4 ++-- libexec/nuageinit/tests/utils.sh | 4 ++-- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua index 1f035036f802..c27b66b23be2 100644 --- a/libexec/nuageinit/nuage.lua +++ b/libexec/nuageinit/nuage.lua @@ -7,12 +7,19 @@ local unistd = require("posix.unistd") local sys_stat = require("posix.sys.stat") local lfs = require("lfs") -local function warnmsg(str) - io.stderr:write(str .. "\n") +local function warnmsg(str, prepend) + if not str then + return + end + local tag = "" + if prepend ~= false then + tag = "nuageinit: " + end + io.stderr:write(tag .. str .. "\n") end -local function errmsg(str) - io.stderr:write(str .. "\n") +local function errmsg(str, prepend) + warnmsg(str, prepend) os.exit(1) end @@ -129,7 +136,7 @@ local function adduser(pwd) local r = os.execute(cmd) if not r then - warnmsg("nuageinit: fail to add user " .. pwd.name) + warnmsg("fail to add user " .. pwd.name) warnmsg(cmd) return nil end @@ -172,7 +179,7 @@ local function addgroup(grp) cmd = cmd .. "groupadd -n " .. grp.name .. extraargs local r = os.execute(cmd) if not r then - warnmsg("nuageinit: fail to add group " .. grp.name) + warnmsg("fail to add group " .. grp.name) warnmsg(cmd) return false end @@ -201,7 +208,7 @@ local function addsshkey(homedir, key) local f = io.open(ak_path, "a") if not f then - warnmsg("nuageinit: impossible to open " .. ak_path) + warnmsg("impossible to open " .. ak_path) return end f:write(key .. "\n") diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit index 50d77dfef9f5..8c289fea6b1d 100755 --- a/libexec/nuageinit/nuageinit +++ b/libexec/nuageinit/nuageinit @@ -9,7 +9,7 @@ local ucl = require("ucl") local yaml = require("yaml") if #arg ~= 2 then - nuage.err("Usage " .. arg[0] .. " [config-2|nocloud]") + nuage.err("Usage " .. arg[0] .. " [config-2|nocloud]", false) end local path = arg[1] local citype = arg[2] @@ -32,7 +32,7 @@ local function open_config(name) nuage.mkdir_p(root .. "/etc/rc.conf.d") local f, err = io.open(root .. "/etc/rc.conf.d/" .. name, "w") if not f then - nuage.err("nuageinit: unable to open " .. name .. " config: " .. err) + nuage.err("unable to open " .. name .. " config: " .. err) end return f end @@ -69,14 +69,14 @@ local function config2_network(p) f:close() local res, err = parser:parse_file(p .. "/network_data.json") if not res then - nuage.warn("nuageinit: error parsing network_data.json: " .. err) + nuage.warn("error parsing network_data.json: " .. err) return end local obj = parser:get_object() local ifaces = get_ifaces() if not ifaces then - nuage.warn("nuageinit: no network interfaces found") + nuage.warn("no network interfaces found") return end local mylinks = {} @@ -167,7 +167,7 @@ if citype == "config-2" then local res, err = parser:parse_file(path .. "/meta_data.json") if not res then - nuage.err("nuageinit: error parsing config-2: meta_data.json: " .. err) + nuage.err("error parsing config-2 meta_data.json: " .. err) end local obj = parser:get_object() if obj.public_keys then @@ -183,12 +183,12 @@ if citype == "config-2" then elseif citype == "nocloud" then local f, err = io.open(path .. "/meta-data") if err then - nuage.err("nuageinit: error parsing nocloud meta-data: " .. err) + nuage.err("error parsing nocloud meta-data: " .. err) end local obj = yaml.eval(f:read("*a")) f:close() if not obj then - nuage.err("nuageinit: error parsing nocloud meta-data") + nuage.err("error parsing nocloud meta-data") end local hostname = obj["local-hostname"] if not hostname then @@ -222,21 +222,21 @@ if line == "#cloud-config" then local obj = yaml.eval(f:read("*a")) f:close() if not obj then - nuage.err("nuageinit: error parsing cloud-config file: " .. ud) + nuage.err("error parsing cloud-config file: " .. ud) end if obj.groups then for n, g in pairs(obj.groups) do if (type(g) == "string") then local r = nuage.addgroup({name = g}) if not r then - nuage.warn("nuageinit: failed to add group: " .. g) + nuage.warn("failed to add group: " .. g) end elseif type(g) == "table" then for k, v in pairs(g) do nuage.addgroup({name = k, members = v}) end else - nuage.warn("nuageinit: invalid type: " .. type(g) .. " for users entry number " .. n) + nuage.warn("invalid type: " .. type(g) .. " for users entry number " .. n) end end end @@ -260,7 +260,7 @@ if line == "#cloud-config" then end end else - nuage.warn("nuageinit: invalid type : " .. type(u) .. " for users entry number " .. n) + nuage.warn("invalid type : " .. type(u) .. " for users entry number " .. n) end ::unext:: end @@ -288,7 +288,7 @@ if line == "#cloud-config" then goto next end if not ifaces[v.match.macaddress] then - nuage.warn("nuageinit: not interface matching: " .. v.match.macaddress) + nuage.warn("not interface matching: " .. v.match.macaddress) goto next end local interface = ifaces[v.match.macaddress] @@ -325,6 +325,6 @@ if line == "#cloud-config" then else local res, err = os.execute(path .. "/" .. ud) if not res then - nuage.err("nuageinit: error executing user-data script: " .. err) + nuage.err("error executing user-data script: " .. err) end end diff --git a/libexec/nuageinit/tests/nuage.sh b/libexec/nuageinit/tests/nuage.sh index 4e2353176b16..6d8a2746de1f 100644 --- a/libexec/nuageinit/tests/nuage.sh +++ b/libexec/nuageinit/tests/nuage.sh @@ -42,7 +42,7 @@ adduser_body() printf "root:*:0:0::0:0:Charlie &:/root:/bin/csh\n" > etc/master.passwd pwd_mkdb -d etc etc/master.passwd printf "wheel:*:0:root\n" > etc/group - atf_check -e inline:"Argument should be a table\nArgument should be a table\n" /usr/libexec/flua $(atf_get_srcdir)/adduser.lua + atf_check -e inline:"nuageinit: Argument should be a table\nnuageinit: Argument should be a table\n" /usr/libexec/flua $(atf_get_srcdir)/adduser.lua test -d home/impossible_username || atf_fail "home not created" atf_check -o inline:"impossible_username::1001:1001::0:0:impossible_username User:/home/impossible_username:/bin/sh\n" grep impossible_username etc/master.passwd } @@ -52,7 +52,7 @@ addgroup_body() export NUAGE_FAKE_ROOTDIR="$(pwd)" mkdir etc printf "wheel:*:0:root\n" > etc/group - atf_check -e inline:"Argument should be a table\nArgument should be a table\n" /usr/libexec/flua $(atf_get_srcdir)/addgroup.lua + atf_check -e inline:"nuageinit: Argument should be a table\nnuageinit: Argument should be a table\n" /usr/libexec/flua $(atf_get_srcdir)/addgroup.lua atf_check -o inline:"impossible_groupname:*:1001:\n" grep impossible_groupname etc/group } diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh index 64ac066fefbf..f3fc55e87523 100644 --- a/libexec/nuageinit/tests/nuageinit.sh +++ b/libexec/nuageinit/tests/nuageinit.sh @@ -22,7 +22,7 @@ args_body() atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit [config-2|nocloud]\n" /usr/libexec/nuageinit atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit [config-2|nocloud]\n" /usr/libexec/nuageinit bla atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit [config-2|nocloud]\n" /usr/libexec/nuageinit bla meh plop - atf_check -s exit:1 -e inline:"Unknown cloud init type: meh\n" /usr/libexec/nuageinit bla meh + atf_check -s exit:1 -e inline:"nuageinit: Unknown cloud init type: meh\n" /usr/libexec/nuageinit bla meh } nocloud_body() @@ -174,7 +174,7 @@ config2_body() { here=$(pwd) mkdir -p media/nuageinit - atf_check -s exit:1 -e match:"nuageinit: error parsing config-2: meta_data.json.*" /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check -s exit:1 -e match:"nuageinit: error parsing config-2 meta_data.json:.*" /usr/libexec/nuageinit ${here}/media/nuageinit config-2 printf "{}" > media/nuageinit/meta_data.json atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 cat > media/nuageinit/meta_data.json << EOF diff --git a/libexec/nuageinit/tests/utils.sh b/libexec/nuageinit/tests/utils.sh index c3b5b8212938..26f117d81d60 100644 --- a/libexec/nuageinit/tests/utils.sh +++ b/libexec/nuageinit/tests/utils.sh @@ -10,12 +10,12 @@ atf_test_case dirname warn_body() { - atf_check -e "inline:plop\n" -s exit:0 /usr/libexec/flua $(atf_get_srcdir)/warn.lua + atf_check -e "inline:nuageinit: plop\n" -s exit:0 /usr/libexec/flua $(atf_get_srcdir)/warn.lua } err_body() { - atf_check -e "inline:plop\n" -s exit:1 /usr/libexec/flua $(atf_get_srcdir)/err.lua + atf_check -e "inline:nuageinit: plop\n" -s exit:1 /usr/libexec/flua $(atf_get_srcdir)/err.lua } dirname_body() From 38bb6f79e39a14ea99f559f59129a4cadf92b569 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Tue, 30 Jul 2024 01:59:16 +0000 Subject: [PATCH 09/12] nuageinit: Standardize user-facing error messages Signed-off-by: Jose Luis Duran --- libexec/nuageinit/nuageinit | 2 +- libexec/nuageinit/tests/nuageinit.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit index 8c289fea6b1d..c8f74d13b7fd 100755 --- a/libexec/nuageinit/nuageinit +++ b/libexec/nuageinit/nuageinit @@ -9,7 +9,7 @@ local ucl = require("ucl") local yaml = require("yaml") if #arg ~= 2 then - nuage.err("Usage " .. arg[0] .. " [config-2|nocloud]", false) + nuage.err("Usage: " .. arg[0] .. " ( | )", false) end local path = arg[1] local citype = arg[2] diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh index f3fc55e87523..6b8ea7ff3328 100644 --- a/libexec/nuageinit/tests/nuageinit.sh +++ b/libexec/nuageinit/tests/nuageinit.sh @@ -19,9 +19,9 @@ atf_test_case config2_network_static_v4 args_body() { - atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit [config-2|nocloud]\n" /usr/libexec/nuageinit - atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit [config-2|nocloud]\n" /usr/libexec/nuageinit bla - atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit [config-2|nocloud]\n" /usr/libexec/nuageinit bla meh plop + atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit ( | )\n" /usr/libexec/nuageinit + atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit ( | )\n" /usr/libexec/nuageinit bla + atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit ( | )\n" /usr/libexec/nuageinit bla meh plop atf_check -s exit:1 -e inline:"nuageinit: Unknown cloud init type: meh\n" /usr/libexec/nuageinit bla meh } From b9ce743c5447e90c2c97f4d49e048c301f708527 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Tue, 30 Jul 2024 01:28:18 +0000 Subject: [PATCH 10/12] nuageinit: Fix passwords The hashed password usually contains a "$" sign, which, when used on a shell, must be escaped. Also, the plain text password may contain special characters that require escaping. Add a quick fix by enclosing it in single quotes. Note that if the plain text password contains a "'", it will still fail. This will be properly fixed in later commits. Some here documents require the document to be a string literal, especially when passing invalid characters. Enclose it in single quotes. Signed-off-by: Jose Luis Duran --- libexec/nuageinit/nuage.lua | 8 ++++---- libexec/nuageinit/tests/nuageinit.sh | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua index c27b66b23be2..4e21405a443b 100644 --- a/libexec/nuageinit/nuage.lua +++ b/libexec/nuageinit/nuage.lua @@ -120,11 +120,11 @@ local function adduser(pwd) local precmd = "" local postcmd = "" if pwd.passwd then - precmd = "echo " .. pwd.passwd .. "| " - postcmd = " -H 0 " + precmd = "echo '" .. pwd.passwd .. "' | " + postcmd = " -H 0" elseif pwd.plain_text_passwd then - precmd = "echo " .. pwd.plain_text_passwd .. "| " - postcmd = " -h 0 " + precmd = "echo '" .. pwd.plain_text_passwd .. "' | " + postcmd = " -h 0" end cmd = precmd .. "pw " if root then diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh index 6b8ea7ff3328..434fb3095929 100644 --- a/libexec/nuageinit/tests/nuageinit.sh +++ b/libexec/nuageinit/tests/nuageinit.sh @@ -81,7 +81,7 @@ EOF wheel:*:0:root users:*:1: EOF - cat > media/nuageinit/user-data << EOF + cat > media/nuageinit/user-data << 'EOF' #cloud-config groups: - admingroup: [root,sys] @@ -103,11 +103,11 @@ cloud-users:*:1002: freebsd:*:1003: foobar:*:1004: EOF - cat > expectedpasswd << EOF + cat > expectedpasswd << 'EOF' root:*:0:0::0:0:Charlie &:/root:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/csh freebsd:freebsd:1001:1003::0:0:FreeBSD User:/home/freebsd:/bin/sh -foobar:H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1002:1004::0:0:Foo B. Bar:/home/foobar:/bin/sh +foobar:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1002:1004::0:0:Foo B. Bar:/home/foobar:/bin/sh EOF sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" ${here}/etc/master.passwd atf_check -o file:expectedpasswd cat ${here}/etc/master.passwd From e72457c4f5166eef2a27249e02f3c1e9a1cf852d Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Tue, 30 Jul 2024 03:26:21 +0000 Subject: [PATCH 11/12] nuageinit: tests: Cleanup - Export NUAGE_FAKE_ROOTDIR only once - Use the header section of the test to require the root user - Use the PWD environment variable - Set the root/sys shell as /bin/sh - Use RFC 5737 reserved IP addresses Signed-off-by: Jose Luis Duran --- libexec/nuageinit/tests/nuage.sh | 14 +-- libexec/nuageinit/tests/nuageinit.sh | 165 ++++++++++++--------------- 2 files changed, 83 insertions(+), 96 deletions(-) diff --git a/libexec/nuageinit/tests/nuage.sh b/libexec/nuageinit/tests/nuage.sh index 6d8a2746de1f..293a0a4a9a83 100644 --- a/libexec/nuageinit/tests/nuage.sh +++ b/libexec/nuageinit/tests/nuage.sh @@ -4,6 +4,8 @@ # SPDX-License-Identifier: BSD-2-Clause # +export NUAGE_FAKE_ROOTDIR="$PWD" + atf_test_case sethostname atf_test_case addsshkey atf_test_case adduser @@ -11,7 +13,6 @@ atf_test_case addgroup sethostname_body() { - export NUAGE_FAKE_ROOTDIR="$(pwd)" atf_check /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua if [ ! -f etc/rc.conf.d/hostname ]; then atf_fail "hostname not written" @@ -32,14 +33,14 @@ addsshkey_body() atf_check -o inline:"mykey\nmykey\n" cat .ssh/authorized_keys } +adduser_head() +{ + atf_set "require.user" root +} adduser_body() { - export NUAGE_FAKE_ROOTDIR="$(pwd)" - if [ $(id -u) -ne 0 ]; then - atf_skip "root required" - fi mkdir etc - printf "root:*:0:0::0:0:Charlie &:/root:/bin/csh\n" > etc/master.passwd + printf "root:*:0:0::0:0:Charlie &:/root:/bin/sh\n" > etc/master.passwd pwd_mkdb -d etc etc/master.passwd printf "wheel:*:0:root\n" > etc/group atf_check -e inline:"nuageinit: Argument should be a table\nnuageinit: Argument should be a table\n" /usr/libexec/flua $(atf_get_srcdir)/adduser.lua @@ -49,7 +50,6 @@ adduser_body() addgroup_body() { - export NUAGE_FAKE_ROOTDIR="$(pwd)" mkdir etc printf "wheel:*:0:root\n" > etc/group atf_check -e inline:"nuageinit: Argument should be a table\nnuageinit: Argument should be a table\n" /usr/libexec/flua $(atf_get_srcdir)/addgroup.lua diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh index 434fb3095929..f7f39ce32ad8 100644 --- a/libexec/nuageinit/tests/nuageinit.sh +++ b/libexec/nuageinit/tests/nuageinit.sh @@ -4,6 +4,8 @@ # SPDX-License-Identifier: BSD-2-Clause # +export NUAGE_FAKE_ROOTDIR="$PWD" + atf_test_case args atf_test_case nocloud atf_test_case nocloud_userdata_script @@ -27,56 +29,51 @@ args_body() nocloud_body() { - here=$(pwd) mkdir -p media/nuageinit - atf_check -s exit:1 -e match:"nuageinit: error parsing nocloud.*" /usr/libexec/nuageinit ${here}/media/nuageinit/ nocloud - export NUAGE_FAKE_ROOTDIR=$(pwd) - printf "instance-id: iid-local01\nlocal-hostname: cloudimg\n" > ${here}/media/nuageinit/meta-data - atf_check -s exit:0 /usr/libexec/nuageinit ${here}/media/nuageinit nocloud + atf_check -s exit:1 -e match:"nuageinit: error parsing nocloud.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit/ nocloud + printf "instance-id: iid-local01\nlocal-hostname: cloudimg\n" > "${PWD}"/media/nuageinit/meta-data + atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname cat > media/nuageinit/meta-data << EOF instance-id: iid-local01 hostname: myhost EOF - atf_check -s exit:0 /usr/libexec/nuageinit ${here}/media/nuageinit nocloud + atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud atf_check -o inline:"hostname=\"myhost\"\n" cat etc/rc.conf.d/hostname } nocloud_userdata_script_body() { - here=$(pwd) mkdir -p media/nuageinit - printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data - printf "#!/bin/sh\necho yeah\n" > ${here}/media/nuageinit/user-data - chmod 755 ${here}/media/nuageinit/user-data - atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit ${here}/media/nuageinit nocloud + 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 } nocloud_user_data_script_body() { - here=$(pwd) mkdir -p media/nuageinit - printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data - printf "#!/bin/sh\necho yeah\n" > ${here}/media/nuageinit/user_data - chmod 755 ${here}/media/nuageinit/user_data - atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit ${here}/media/nuageinit nocloud + 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 } +nocloud_userdata_cloudconfig_users_head() +{ + atf_set "require.user" root +} nocloud_userdata_cloudconfig_users_body() { - here=$(pwd) - export NUAGE_FAKE_ROOTDIR=$(pwd) - if [ $(id -u) -ne 0 ]; then - atf_skip "root required" - fi mkdir -p media/nuageinit - printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data + printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data mkdir -p etc cat > etc/master.passwd << EOF -root:*:0:0::0:0:Charlie &:/root:/bin/csh -sys:*:1:0::0:0:Sys:/home/sys:/bin/csh +root:*:0:0::0:0:Charlie &:/root:/bin/sh +sys:*:1:0::0:0:Sys:/home/sys:/bin/sh EOF - pwd_mkdb -d etc ${here}/etc/master.passwd + pwd_mkdb -d etc "${PWD}"/etc/master.passwd cat > etc/group << EOF wheel:*:0:root users:*:1: @@ -94,7 +91,7 @@ users: groups: users passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/ EOF - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit nocloud + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud cat > expectedgroup << EOF wheel:*:0:root,freebsd users:*:1:foobar @@ -104,33 +101,33 @@ freebsd:*:1003: foobar:*:1004: EOF cat > expectedpasswd << 'EOF' -root:*:0:0::0:0:Charlie &:/root:/bin/csh -sys:*:1:0::0:0:Sys:/home/sys:/bin/csh +root:*:0:0::0:0:Charlie &:/root:/bin/sh +sys:*:1:0::0:0:Sys:/home/sys:/bin/sh freebsd:freebsd:1001:1003::0:0:FreeBSD User:/home/freebsd:/bin/sh foobar:$6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/:1002:1004::0:0:Foo B. Bar:/home/foobar:/bin/sh EOF - sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" ${here}/etc/master.passwd - atf_check -o file:expectedpasswd cat ${here}/etc/master.passwd - atf_check -o file:expectedgroup cat ${here}/etc/group + sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" "${PWD}"/etc/master.passwd + atf_check -o file:expectedpasswd cat "${PWD}"/etc/master.passwd + atf_check -o file:expectedgroup cat "${PWD}"/etc/group } +nocloud_network_head() +{ + atf_set "require.user" root +} nocloud_network_body() { - here=$(pwd) mkdir -p media/nuageinit mkdir -p etc cat > etc/master.passwd << EOF -root:*:0:0::0:0:Charlie &:/root:/bin/csh -sys:*:1:0::0:0:Sys:/home/sys:/bin/csh +root:*:0:0::0:0:Charlie &:/root:/bin/sh +sys:*:1:0::0:0:Sys:/home/sys:/bin/sh EOF - pwd_mkdb -d etc ${here}/etc/master.passwd + pwd_mkdb -d etc "${PWD}"/etc/master.passwd cat > etc/group << EOF wheel:*:0:root users:*:1: EOF - if [ $(id -u) -ne 0 ]; then - atf_skip "root required" - fi mynetworks=$(ifconfig -l ether) if [ -z "$mynetworks" ]; then atf_skip "a network interface is needed" @@ -138,7 +135,7 @@ EOF set -- $mynetworks myiface=$1 myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }') - printf "instance-id: iid-local01\n" > ${here}/media/nuageinit/meta-data + printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data cat > media/nuageinit/user-data << EOF #cloud-config network: @@ -149,51 +146,48 @@ network: match: macaddress: "$myaddr" addresses: - - 192.168.14.2/24 - - 2001:1::1/64 - gateway4: 192.168.14.1 - gateway6: 2001:1::2 + - 192.0.2.2/24 + - 2001:db8::2/64 + gateway4: 192.0.2.1 + gateway6: 2001:db8::1 EOF - export NUAGE_FAKE_ROOTDIR=$(pwd) - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit nocloud + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud cat > network << EOF -ifconfig_${myiface}="inet 192.168.14.2/24" -ifconfig_${myiface}_ipv6="inet6 2001:1::1/64" +ifconfig_${myiface}="inet 192.0.2.2/24" +ifconfig_${myiface}_ipv6="inet6 2001:db8::2/64" ipv6_network_interfaces="${myiface}" ipv6_default_interface="${myiface}" EOF cat > routing << EOF -defaultrouter="192.168.14.1" -ipv6_defaultrouter="2001:1::2" -ipv6_route_${myiface}="2001:1::2 -prefixlen 128 -interface ${myiface}" +defaultrouter="192.0.2.1" +ipv6_defaultrouter="2001:db8::1" +ipv6_route_${myiface}="2001:db8::1 -prefixlen 128 -interface ${myiface}" EOF - atf_check -o file:network cat ${here}/etc/rc.conf.d/network - atf_check -o file:routing cat ${here}/etc/rc.conf.d/routing + atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network + atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing } + config2_body() { - here=$(pwd) mkdir -p media/nuageinit - atf_check -s exit:1 -e match:"nuageinit: error parsing config-2 meta_data.json:.*" /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check -s exit:1 -e match:"nuageinit: error parsing config-2 meta_data.json:.*" /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2 printf "{}" > media/nuageinit/meta_data.json - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2 cat > media/nuageinit/meta_data.json << EOF { "hostname": "cloudimg" } EOF - export NUAGE_FAKE_ROOTDIR=$(pwd) - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2 atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname } +config2_pubkeys_head() +{ + atf_set "require.user" root +} config2_pubkeys_body() { - here=$(pwd) - export NUAGE_FAKE_ROOTDIR=$(pwd) - if [ $(id -u) -ne 0 ]; then - atf_skip "root required" - fi mkdir -p media/nuageinit touch media/nuageinit/meta_data.json cat > media/nuageinit/user-data << EOF @@ -203,26 +197,24 @@ ssh_authorized_keys: EOF mkdir -p etc cat > etc/master.passwd << EOF -root:*:0:0::0:0:Charlie &:/root:/bin/csh -sys:*:1:0::0:0:Sys:/home/sys:/bin/csh +root:*:0:0::0:0:Charlie &:/root:/bin/sh +sys:*:1:0::0:0:Sys:/home/sys:/bin/sh EOF - pwd_mkdb -d etc ${here}/etc/master.passwd + pwd_mkdb -d etc "${PWD}"/etc/master.passwd cat > etc/group << EOF wheel:*:0:root users:*:1: EOF - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2 atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys } - +config2_pubkeys_user_data_head() +{ + atf_set "require.user" root +} config2_pubkeys_user_data_body() { - here=$(pwd) - export NUAGE_FAKE_ROOTDIR=$(pwd) - if [ $(id -u) -ne 0 ]; then - atf_skip "root required" - fi mkdir -p media/nuageinit touch media/nuageinit/meta_data.json cat > media/nuageinit/user_data << EOF @@ -232,15 +224,15 @@ ssh_authorized_keys: EOF mkdir -p etc cat > etc/master.passwd << EOF -root:*:0:0::0:0:Charlie &:/root:/bin/csh -sys:*:1:0::0:0:Sys:/home/sys:/bin/csh +root:*:0:0::0:0:Charlie &:/root:/bin/sh +sys:*:1:0::0:0:Sys:/home/sys:/bin/sh EOF - pwd_mkdb -d etc ${here}/etc/master.passwd + pwd_mkdb -d etc "${PWD}"/etc/master.passwd cat > etc/group << EOF wheel:*:0:root users:*:1: EOF - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2 atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys } @@ -292,7 +284,6 @@ EOF config2_network_body() { - here=$(pwd) mkdir -p media/nuageinit printf "{}" > media/nuageinit/meta_data.json mynetworks=$(ifconfig -l ether) @@ -322,7 +313,7 @@ cat > media/nuageinit/network_data.json << EOF "type": "ipv6", "link": "iface0", // supports condensed IPv6 with CIDR netmask - "ip_address": "2001:cdba::3257:9652/24", + "ip_address": "2001:db8::3257:9652/64", "gateway": "fd00::1", "routes": [ { @@ -341,11 +332,10 @@ cat > media/nuageinit/network_data.json << EOF ] } EOF - export NUAGE_FAKE_ROOTDIR=$(pwd) - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2 cat > network << EOF ifconfig_${myiface}="DHCP" -ifconfig_${myiface}_ipv6="inet6 2001:cdba::3257:9652/24" +ifconfig_${myiface}_ipv6="inet6 2001:db8::3257:9652/64" ipv6_network_interfaces="${myiface}" ipv6_default_interface="${myiface}" EOF @@ -354,13 +344,12 @@ ipv6_defaultrouter="fd00::1" ipv6_route_${myiface}="fd00::1 -prefixlen 128 -interface ${myiface}" ipv6_static_routes="${myiface}" EOF - atf_check -o file:network cat ${here}/etc/rc.conf.d/network - atf_check -o file:routing cat ${here}/etc/rc.conf.d/routing + atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network + atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing } config2_network_static_v4_body() { - here=$(pwd) mkdir -p media/nuageinit printf "{}" > media/nuageinit/meta_data.json mynetworks=$(ifconfig -l ether) @@ -402,9 +391,7 @@ cat > media/nuageinit/network_data.json << EOF ] } EOF - - export NUAGE_FAKE_ROOTDIR=$(pwd) - atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 + atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2 cat > network << EOF ifconfig_${myiface}="inet 10.184.0.244 netmask 255.255.240.0" EOF @@ -413,8 +400,8 @@ route_cloudinit1_${myiface}="-net 10.0.0.0 11.0.0.1 255.0.0.0" defaultrouter="23.253.157.1" static_routes="cloudinit1_${myiface}" EOF - atf_check -o file:network cat ${here}/etc/rc.conf.d/network - atf_check -o file:routing cat ${here}/etc/rc.conf.d/routing + atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network + atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing } atf_init_test_cases() From 120740221fd4a4577e63e6c279f9873cabe449d0 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Tue, 30 Jul 2024 04:47:04 +0000 Subject: [PATCH 12/12] release: basic-cloudinit improve default image - Add the firstboot-freebsd-update package, as long as we do not have pkgbase, this is needed - Support SLAAC by default to complement DHCPv4 (use SYNCDHP instead) Signed-off-by: Jose Luis Duran --- release/tools/basic-cloudinit.conf | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/release/tools/basic-cloudinit.conf b/release/tools/basic-cloudinit.conf index da4bed5ea5b5..a03c11603ed6 100644 --- a/release/tools/basic-cloudinit.conf +++ b/release/tools/basic-cloudinit.conf @@ -1,6 +1,4 @@ #!/bin/sh -# -# # Should be enough for base image, image can be resized in needed export VMSIZE=5g @@ -9,13 +7,17 @@ export VMSIZE=5g export CONFIG_DRIVE=YES export CONFIG_DRIVE_SIZE=1M +# Packages to install into the image we're creating. +# * firstboot-freebsd-update, to install security updates at first boot. +export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} firstboot-freebsd-update" + # Set to a list of third-party software to enable in rc.conf(5). -export VM_RC_LIST="sshd growfs nuageinit" +export VM_RC_LIST="${VM_RC_LIST} firstboot_freebsd_update growfs sshd nuageinit" vm_extra_pre_umount() { cat << EOF >> ${DESTDIR}/etc/rc.conf dumpdev="AUTO" -ifconfig_DEFAULT="DHCP" +ifconfig_DEFAULT="SYNCDHCP accept_rtadv" sshd_enable="YES" EOF @@ -25,7 +27,8 @@ beastie_disable="YES" loader_logo="none" console="comconsole,vidconsole" EOF - cat <> ${DESTDIR}/etc/ssh/sshd_config + + cat << EOF >> ${DESTDIR}/etc/ssh/sshd_config PasswordAuthentication yes UsePAM no EOF