Merge branch 'freebsd/current/main' into hardened/current/master

This commit is contained in:
HardenedBSD Sync Services 2024-09-26 06:01:35 -06:00
commit 8a38e94320
No known key found for this signature in database
22 changed files with 416 additions and 348 deletions

View File

@ -1,15 +1,25 @@
---
-- SPDX-License-Identifier: BSD-2-Clause -- SPDX-License-Identifier: BSD-2-Clause
-- --
-- Copyright(c) 2022 Baptiste Daroussin <bapt@FreeBSD.org> -- Copyright(c) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
local pu = require("posix.unistd") local unistd = require("posix.unistd")
local sys_stat = require("posix.sys.stat")
local lfs = require("lfs")
local function warnmsg(str) local function warnmsg(str, prepend)
io.stderr:write(str.."\n") if not str then
return
end
local tag = ""
if prepend ~= false then
tag = "nuageinit: "
end
io.stderr:write(tag .. str .. "\n")
end end
local function errmsg(str) local function errmsg(str, prepend)
io.stderr:write(str.."\n") warnmsg(str, prepend)
os.exit(1) os.exit(1)
end end
@ -28,15 +38,17 @@ local function mkdir_p(path)
if lfs.attributes(path, "mode") ~= nil then if lfs.attributes(path, "mode") ~= nil then
return true return true
end end
local r,err = mkdir_p(dirname(path)) local r, err = mkdir_p(dirname(path))
if not r then if not r then
return nil,err.." (creating "..path..")" return nil, err .. " (creating " .. path .. ")"
end end
return lfs.mkdir(path) return lfs.mkdir(path)
end end
local function sethostname(hostname) local function sethostname(hostname)
if hostname == nil then return end if hostname == nil then
return
end
local root = os.getenv("NUAGE_FAKE_ROOTDIR") local root = os.getenv("NUAGE_FAKE_ROOTDIR")
if not root then if not root then
root = "" root = ""
@ -44,12 +56,12 @@ local function sethostname(hostname)
local hostnamepath = root .. "/etc/rc.conf.d/hostname" local hostnamepath = root .. "/etc/rc.conf.d/hostname"
mkdir_p(dirname(hostnamepath)) mkdir_p(dirname(hostnamepath))
local f,err = io.open(hostnamepath, "w") local f, err = io.open(hostnamepath, "w")
if not f then if not f then
warnmsg("Impossible to open "..hostnamepath .. ":" ..err) warnmsg("Impossible to open " .. hostnamepath .. ":" .. err)
return return
end end
f:write("hostname=\""..hostname.."\"\n") f:write('hostname="' .. hostname .. '"\n')
f:close() f:close()
end end
@ -62,7 +74,7 @@ local function splitlist(list)
elseif type(list) == "table" then elseif type(list) == "table" then
ret = list ret = list
else else
warnmsg("Invalid type ".. type(list) ..", expecting table or string") warnmsg("Invalid type " .. type(list) .. ", expecting table or string")
end end
return ret return ret
end end
@ -77,7 +89,7 @@ local function adduser(pwd)
if root then if root then
cmd = cmd .. "-R " .. root .. " " cmd = cmd .. "-R " .. root .. " "
end 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") local pwdstr = f:read("*a")
f:close() f:close()
if pwdstr:len() ~= 0 then if pwdstr:len() ~= 0 then
@ -89,10 +101,10 @@ local function adduser(pwd)
if not pwd.homedir then if not pwd.homedir then
pwd.homedir = "/home/" .. pwd.name pwd.homedir = "/home/" .. pwd.name
end end
local extraargs="" local extraargs = ""
if pwd.groups then if pwd.groups then
local list = splitlist(pwd.groups) local list = splitlist(pwd.groups)
extraargs = " -G ".. table.concat(list, ',') extraargs = " -G " .. table.concat(list, ",")
end end
-- pw will automatically create a group named after the username -- pw will automatically create a group named after the username
-- do not add a -g option in this case -- do not add a -g option in this case
@ -108,23 +120,23 @@ local function adduser(pwd)
local precmd = "" local precmd = ""
local postcmd = "" local postcmd = ""
if pwd.passwd then if pwd.passwd then
precmd = "echo "..pwd.passwd .. "| " precmd = "echo '" .. pwd.passwd .. "' | "
postcmd = " -H 0 " postcmd = " -H 0"
elseif pwd.plain_text_passwd then elseif pwd.plain_text_passwd then
precmd = "echo "..pwd.plain_text_passwd .. "| " precmd = "echo '" .. pwd.plain_text_passwd .. "' | "
postcmd = " -h 0 " postcmd = " -h 0"
end end
cmd = precmd .. "pw " cmd = precmd .. "pw "
if root then if root then
cmd = cmd .. "-R " .. root .. " " cmd = cmd .. "-R " .. root .. " "
end end
cmd = cmd .. "useradd -n ".. pwd.name .. " -M 0755 -w none " cmd = cmd .. "useradd -n " .. pwd.name .. " -M 0755 -w none "
cmd = cmd .. extraargs .. " -c '".. pwd.gecos cmd = cmd .. extraargs .. " -c '" .. pwd.gecos
cmd = cmd .. "' -d '" .. pwd.homedir .. "' -s "..pwd.shell .. postcmd cmd = cmd .. "' -d '" .. pwd.homedir .. "' -s " .. pwd.shell .. postcmd
local r = os.execute(cmd) local r = os.execute(cmd)
if not r then if not r then
warnmsg("nuageinit: fail to add user "..pwd.name); warnmsg("fail to add user " .. pwd.name)
warnmsg(cmd) warnmsg(cmd)
return nil return nil
end end
@ -149,7 +161,7 @@ local function addgroup(grp)
if root then if root then
cmd = cmd .. "-R " .. root .. " " cmd = cmd .. "-R " .. root .. " "
end 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") local grpstr = f:read("*a")
f:close() f:close()
if grpstr:len() ~= 0 then if grpstr:len() ~= 0 then
@ -158,16 +170,16 @@ local function addgroup(grp)
local extraargs = "" local extraargs = ""
if grp.members then if grp.members then
local list = splitlist(grp.members) local list = splitlist(grp.members)
extraargs = " -M " .. table.concat(list, ',') extraargs = " -M " .. table.concat(list, ",")
end end
cmd = "pw " cmd = "pw "
if root then if root then
cmd = cmd .. "-R " .. root .. " " cmd = cmd .. "-R " .. root .. " "
end end
cmd = cmd .. "groupadd -n ".. grp.name .. extraargs cmd = cmd .. "groupadd -n " .. grp.name .. extraargs
local r = os.execute(cmd) local r = os.execute(cmd)
if not r then if not r then
warnmsg("nuageinit: fail to add group ".. grp.name); warnmsg("fail to add group " .. grp.name)
warnmsg(cmd) warnmsg(cmd)
return false return false
end end
@ -196,30 +208,30 @@ local function addsshkey(homedir, key)
local f = io.open(ak_path, "a") local f = io.open(ak_path, "a")
if not f then if not f then
warnmsg("nuageinit: impossible to open "..ak_path) warnmsg("impossible to open " .. ak_path)
return return
end end
f:write(key .. "\n") f:write(key .. "\n")
f:close() f:close()
if chownak then if chownak then
os.execute("chmod 0600 " .. ak_path) sys_stat.chmod(ak_path, 384)
pu.chown(ak_path, dirattrs.uid, dirattrs.gid) unistd.chown(ak_path, dirattrs.uid, dirattrs.gid)
end end
if chowndotssh then if chowndotssh then
os.execute("chmod 0700 " .. dotssh_path) sys_stat.chmod(dotssh_path, 448)
pu.chown(dotssh_path, dirattrs.uid, dirattrs.gid) unistd.chown(dotssh_path, dirattrs.uid, dirattrs.gid)
end end
end end
local n = { local n = {
warn = warnmsg, warn = warnmsg,
err = errmsg, err = errmsg,
dirname = dirname,
mkdir_p = mkdir_p,
sethostname = sethostname, sethostname = sethostname,
adduser = adduser, adduser = adduser,
addgroup = addgroup, addgroup = addgroup,
addsshkey = addsshkey, addsshkey = addsshkey
dirname = dirname,
mkdir_p = mkdir_p,
} }
return n return n

View File

@ -1,18 +1,18 @@
#!/usr/libexec/flua #!/usr/libexec/flua
---
-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD -- SPDX-License-Identifier: BSD-2-Clause-FreeBSD
-- --
-- Copyright(c) 2022 Baptiste Daroussin <bapt@FreeBSD.org> -- Copyright(c) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
local nuage = require("nuage") local nuage = require("nuage")
local ucl = require("ucl")
local yaml = require("yaml") local yaml = require("yaml")
if #arg ~= 2 then if #arg ~= 2 then
nuage.err("Usage ".. arg[0] .." <cloud-init directory> [config-2|nocloud]") nuage.err("Usage: " .. arg[0] .. " <cloud-init-directory> (<config-2> | <nocloud>)", false)
end end
local path = arg[1] local path = arg[1]
local citype = arg[2] local citype = arg[2]
local ucl = require("ucl")
local default_user = { local default_user = {
name = "freebsd", name = "freebsd",
@ -30,9 +30,9 @@ end
local function open_config(name) local function open_config(name)
nuage.mkdir_p(root .. "/etc/rc.conf.d") 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 if not f then
nuage.err("nuageinit: unable to open "..name.." config: " .. err) nuage.err("unable to open " .. name .. " config: " .. err)
end end
return f return f
end end
@ -40,17 +40,17 @@ end
local function get_ifaces() local function get_ifaces()
local parser = ucl.parser() local parser = ucl.parser()
-- grab ifaces -- grab ifaces
local ns = io.popen('netstat -i --libxo json') local ns = io.popen("netstat -i --libxo json")
local netres = ns:read("*a") local netres = ns:read("*a")
ns:close() ns:close()
local res,err = parser:parse_string(netres) local res, err = parser:parse_string(netres)
if not res then if not res then
nuage.warn("Error parsing netstat -i --libxo json outout: " .. err) nuage.warn("Error parsing netstat -i --libxo json outout: " .. err)
return nil return nil
end end
local ifaces = parser:get_object() local ifaces = parser:get_object()
local myifaces = {} local myifaces = {}
for _,iface in pairs(ifaces["statistics"]["interface"]) do for _, iface in pairs(ifaces["statistics"]["interface"]) do
if iface["network"]:match("<Link#%d>") then if iface["network"]:match("<Link#%d>") then
local s = iface["address"] local s = iface["address"]
myifaces[s:lower()] = iface["name"] myifaces[s:lower()] = iface["name"]
@ -67,20 +67,20 @@ local function config2_network(p)
return return
end end
f:close() 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 if not res then
nuage.warn("nuageinit: error parsing network_data.json: " .. err) nuage.warn("error parsing network_data.json: " .. err)
return return
end end
local obj = parser:get_object() local obj = parser:get_object()
local ifaces = get_ifaces() local ifaces = get_ifaces()
if not ifaces then if not ifaces then
nuage.warn("nuageinit: no network interfaces found") nuage.warn("no network interfaces found")
return return
end end
local mylinks = {} local mylinks = {}
for _,v in pairs(obj["links"]) do for _, v in pairs(obj["links"]) do
local s = v["ethernet_mac_address"]:lower() local s = v["ethernet_mac_address"]:lower()
mylinks[v["id"]] = ifaces[s] mylinks[v["id"]] = ifaces[s]
end end
@ -91,66 +91,72 @@ local function config2_network(p)
local ipv6 = {} local ipv6 = {}
local ipv6_routes = {} local ipv6_routes = {}
local ipv4 = {} local ipv4 = {}
for _,v in pairs(obj["networks"]) do for _, v in pairs(obj["networks"]) do
local interface = mylinks[v["link"]] local interface = mylinks[v["link"]]
if v["type"] == "ipv4_dhcp" then if v["type"] == "ipv4_dhcp" then
network:write("ifconfig_"..interface.."=\"DHCP\"\n") network:write("ifconfig_" .. interface .. '="DHCP"\n')
end end
if v["type"] == "ipv4" then 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 if v["gateway"] then
routing:write("defaultrouter=\""..v["gateway"].."\"\n") routing:write('defaultrouter="' .. v["gateway"] .. '"\n')
end end
if v["routes"] then 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 local rname = "cloudinit" .. i .. "_" .. interface
if v["gateway"] and v["gateway"] == r["gateway"] then goto next end if v["gateway"] and v["gateway"] == r["gateway"] then
if r["network"] == "0.0.0.0" then
routing:write("defaultrouter=\""..r["gateway"].."\"\n")
goto next goto next
end end
routing:write("route_".. rname .. "=\"-net ".. r["network"] .. " ") if r["network"] == "0.0.0.0" then
routing:write(r["gateway"] .. " " .. r["netmask"] .. "\"\n") 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 ipv4[#ipv4 + 1] = rname
::next:: ::next::
end end
end end
end end
if v["type"] == "ipv6" then if v["type"] == "ipv6" then
ipv6[#ipv6+1] = interface ipv6[#ipv6 + 1] = interface
ipv6_routes[#ipv6_routes+1] = interface ipv6_routes[#ipv6_routes + 1] = interface
network:write("ifconfig_"..interface.."_ipv6=\"inet6 "..v["ip_address"].."\"\n") network:write("ifconfig_" .. interface .. '_ipv6="inet6 ' .. v["ip_address"] .. '"\n')
if v["gateway"] then if v["gateway"] then
routing:write("ipv6_defaultrouter=\""..v["gateway"].."\"\n") routing:write('ipv6_defaultrouter="' .. v["gateway"] .. '"\n')
routing:write("ipv6_route_"..interface.."=\""..v["gateway"]) routing:write("ipv6_route_" .. interface .. '="' .. v["gateway"])
routing:write(" -prefixlen 128 -interface "..interface.."\"\n") routing:write(" -prefixlen 128 -interface " .. interface .. '"\n')
end end
-- TODO compute the prefixlen for the routes -- TODO compute the prefixlen for the routes
--if v["routes"] then --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"]] -- local rname = "cloudinit" .. i .. "_" .. mylinks[v["link"]]
-- -- skip all the routes which are already covered by the default gateway, some provider -- -- skip all the routes which are already covered by the default gateway, some provider
-- -- still list plenty of them. -- -- still list plenty of them.
-- if v["gateway"] == r["gateway"] then goto next end -- if v["gateway"] == r["gateway"] then
-- routing:write("ipv6_route_" .. rname .. "\"\n") -- goto next
-- ipv6_routes[#ipv6_routes+1] = rname -- end
-- routing:write("ipv6_route_" .. rname .. '"\n')
-- ipv6_routes[#ipv6_routes + 1] = rname
-- ::next:: -- ::next::
-- end -- end
--end --end
end end
end end
if #ipv4 > 0 then if #ipv4 > 0 then
routing:write("static_routes=\"") routing:write('static_routes="')
routing:write(table.concat(ipv4, " ") .. "\"\n") routing:write(table.concat(ipv4, " ") .. '"\n')
end end
if #ipv6 > 0 then if #ipv6 > 0 then
network:write("ipv6_network_interfaces=\"") network:write('ipv6_network_interfaces="')
network:write(table.concat(ipv6, " ") .. "\"\n") network:write(table.concat(ipv6, " ") .. '"\n')
network:write("ipv6_default_interface=\""..ipv6[1].."\"\n") network:write('ipv6_default_interface="' .. ipv6[1] .. '"\n')
end end
if #ipv6_routes > 0 then if #ipv6_routes > 0 then
routing:write("ipv6_static_routes=\"") routing:write('ipv6_static_routes="')
routing:write(table.concat(ipv6, " ") .. "\"\n") routing:write(table.concat(ipv6, " ") .. '"\n')
end end
network:close() network:close()
routing:close() routing:close()
@ -158,10 +164,10 @@ end
if citype == "config-2" then if citype == "config-2" then
local parser = ucl.parser() 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 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 end
local obj = parser:get_object() local obj = parser:get_object()
if obj.public_keys then if obj.public_keys then
@ -175,32 +181,32 @@ if citype == "config-2" then
-- network -- network
config2_network(path) config2_network(path)
elseif citype == "nocloud" then elseif citype == "nocloud" then
local f,err = io.open(path.."/meta-data") local f, err = io.open(path .. "/meta-data")
if err then if err then
nuage.err("nuageinit: error parsing nocloud meta-data: ".. err) nuage.err("error parsing nocloud meta-data: " .. err)
end end
local obj = yaml.eval(f:read("*a")) local obj = yaml.eval(f:read("*a"))
f:close() f:close()
if not obj then if not obj then
nuage.err("nuageinit: error parsing nocloud meta-data") nuage.err("error parsing nocloud meta-data")
end end
local hostname = obj['local-hostname'] local hostname = obj["local-hostname"]
if not hostname then if not hostname then
hostname = obj['hostname'] hostname = obj["hostname"]
end end
if hostname then if hostname then
nuage.sethostname(hostname) nuage.sethostname(hostname)
end end
else else
nuage.err("Unknown cloud init type: ".. citype) nuage.err("Unknown cloud init type: " .. citype)
end end
-- deal with user-data -- deal with user-data
local ud = nil local ud = nil
local f = nil local f = nil
userdatas = { "user-data", "user_data" } userdatas = {"user-data", "user_data"}
for _,v in pairs(userdatas) do for _, v in pairs(userdatas) do
f = io.open(path..'/' .. v, "r") f = io.open(path .. "/" .. v, "r")
if f then if f then
ud = v ud = v
break break
@ -209,33 +215,33 @@ end
if not f then if not f then
os.exit(0) os.exit(0)
end end
local line = f:read('*l') local line = f:read("*l")
f:close() f:close()
if line == "#cloud-config" then if line == "#cloud-config" then
f = io.open(path.."/" .. ud) f = io.open(path .. "/" .. ud)
local obj = yaml.eval(f:read("*a")) local obj = yaml.eval(f:read("*a"))
f:close() f:close()
if not obj then if not obj then
nuage.err("nuageinit: error parsing cloud-config file: " .. ud) nuage.err("error parsing cloud-config file: " .. ud)
end end
if obj.groups then 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 if (type(g) == "string") then
local r = nuage.addgroup({name = g}) local r = nuage.addgroup({name = g})
if not r then if not r then
nuage.warn("nuageinit: failed to add group: ".. g) nuage.warn("failed to add group: " .. g)
end end
elseif type(g) == "table" then 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}) nuage.addgroup({name = k, members = v})
end end
else 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 end
end end
if obj.users then 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 type(u) == "string" then
if u == "default" then if u == "default" then
nuage.adduser(default_user) nuage.adduser(default_user)
@ -249,12 +255,12 @@ if line == "#cloud-config" then
end end
local homedir = nuage.adduser(u) local homedir = nuage.adduser(u)
if u.ssh_authorized_keys then 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) nuage.addsshkey(homedir, v)
end end
end end
else 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 end
::unext:: ::unext::
end end
@ -264,7 +270,7 @@ if line == "#cloud-config" then
end end
if obj.ssh_authorized_keys then if obj.ssh_authorized_keys then
local homedir = nuage.adduser(default_user) 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) nuage.addsshkey(homedir, k)
end end
end end
@ -273,48 +279,52 @@ if line == "#cloud-config" then
nuage.mkdir_p(root .. "/etc/rc.conf.d") nuage.mkdir_p(root .. "/etc/rc.conf.d")
local network = open_config("network") local network = open_config("network")
local routing = open_config("routing") local routing = open_config("routing")
local ipv6={} local ipv6 = {}
for _,v in pairs(obj.network.ethernets) do for _, v in pairs(obj.network.ethernets) do
if not v.match then goto next end if not v.match then
if not v.match.macaddress then goto next end goto next
end
if not v.match.macaddress then
goto next
end
if not ifaces[v.match.macaddress] then 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 goto next
end end
local interface = ifaces[v.match.macaddress] local interface = ifaces[v.match.macaddress]
if v.dhcp4 then if v.dhcp4 then
network:write("ifconfig_"..interface.."=\"DHCP\"\n") network:write("ifconfig_" .. interface .. '="DHCP"\n')
elseif v.addresses then 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 if a:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)") then
network:write("ifconfig_"..interface.."=\"inet "..a.."\"\n") network:write("ifconfig_" .. interface .. '="inet ' .. a .. '"\n')
else else
network:write("ifconfig_"..interface.."_ipv6=\"inet6 "..a.."\"\n") network:write("ifconfig_" .. interface .. '_ipv6="inet6 ' .. a .. '"\n')
ipv6[#ipv6 +1] = interface ipv6[#ipv6 + 1] = interface
end end
end end
end end
if v.gateway4 then if v.gateway4 then
routing:write("defaultrouter=\""..v.gateway4.."\"\n") routing:write('defaultrouter="' .. v.gateway4 .. '"\n')
end end
if v.gateway6 then if v.gateway6 then
routing:write("ipv6_defaultrouter=\""..v.gateway6.."\"\n") routing:write('ipv6_defaultrouter="' .. v.gateway6 .. '"\n')
routing:write("ipv6_route_"..interface.."=\""..v.gateway6) routing:write("ipv6_route_" .. interface .. '="' .. v.gateway6)
routing:write(" -prefixlen 128 -interface "..interface.."\"\n") routing:write(" -prefixlen 128 -interface " .. interface .. '"\n')
end end
::next:: ::next::
end end
if #ipv6 > 0 then if #ipv6 > 0 then
network:write("ipv6_network_interfaces=\"") network:write('ipv6_network_interfaces="')
network:write(table.concat(ipv6, " ") .. "\"\n") network:write(table.concat(ipv6, " ") .. '"\n')
network:write("ipv6_default_interface=\""..ipv6[1].."\"\n") network:write('ipv6_default_interface="' .. ipv6[1] .. '"\n')
end end
network:close() network:close()
routing:close() routing:close()
end end
else else
local res,err = os.execute(path..'/' .. ud) local res, err = os.execute(path .. "/" .. ud)
if not res then if not res then
nuage.err("nuageinit: error executing user-data script: ".. err) nuage.err("error executing user-data script: " .. err)
end end
end end

View File

@ -2,12 +2,12 @@ PACKAGE= tests
ATF_TESTS_SH= nuage utils nuageinit ATF_TESTS_SH= nuage utils nuageinit
${PACKAGE}FILES+= warn.lua ${PACKAGE}FILES+= addgroup.lua
${PACKAGE}FILES+= err.lua
${PACKAGE}FILES+= dirname.lua
${PACKAGE}FILES+= sethostname.lua
${PACKAGE}FILES+= addsshkey.lua ${PACKAGE}FILES+= addsshkey.lua
${PACKAGE}FILES+= adduser.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 <bsd.test.mk> .include <bsd.test.mk>

View File

@ -1,6 +1,7 @@
#!/usr/libexec/flua #!/usr/libexec/flua
local n = require("nuage") local n = require("nuage")
if n.addgroup() then if n.addgroup() then
n.err("addgroup should not accept empty value") n.err("addgroup should not accept empty value")
end end

View File

@ -1,2 +1,5 @@
#!/usr/libexec/flua
local n = require("nuage") local n = require("nuage")
n.addsshkey(".", "mykey") n.addsshkey(".", "mykey")

View File

@ -1,6 +1,7 @@
#!/usr/libexec/flua #!/usr/libexec/flua
local n = require("nuage") local n = require("nuage")
if n.adduser() then if n.adduser() then
n.err("adduser should not accept empty value") n.err("adduser should not accept empty value")
end end

View File

@ -1,8 +1,11 @@
#!/usr/libexec/flua
local n = require("nuage") local n = require("nuage")
print(n.dirname("/my/path/path1")) print(n.dirname("/my/path/path1"))
if n.dirname("path") then if n.dirname("path") then
nuage.err("Expecting nil for n.dirname(\"path\")") n.err('Expecting nil for n.dirname("path")')
end end
if n.dirname() then if n.dirname() then
nuage.err("Expecting nil for n.dirname") n.err("Expecting nil for n.dirname")
end end

View File

@ -1,4 +1,5 @@
#!/usr/libexec/flua #!/usr/libexec/flua
local n = require("nuage") local n = require("nuage")
n.err("plop") n.err("plop")

View File

@ -1,10 +1,18 @@
#-
# Copyright (c) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
#
# SPDX-License-Identifier: BSD-2-Clause
#
export NUAGE_FAKE_ROOTDIR="$PWD"
atf_test_case sethostname atf_test_case sethostname
atf_test_case addsshkey atf_test_case addsshkey
atf_test_case adduser atf_test_case adduser
atf_test_case addgroup atf_test_case addgroup
sethostname_body() { sethostname_body()
export NUAGE_FAKE_ROOTDIR="$(pwd)" {
atf_check /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua atf_check /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua
if [ ! -f etc/rc.conf.d/hostname ]; then if [ ! -f etc/rc.conf.d/hostname ]; then
atf_fail "hostname not written" atf_fail "hostname not written"
@ -12,7 +20,8 @@ sethostname_body() {
atf_check -o inline:"hostname=\"myhostname\"\n" cat etc/rc.conf.d/hostname 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 atf_check /usr/libexec/flua $(atf_get_srcdir)/addsshkey.lua
if [ ! -f .ssh/authorized_keys ]; then if [ ! -f .ssh/authorized_keys ]; then
atf_fail "ssh key not added" atf_fail "ssh key not added"
@ -24,29 +33,31 @@ addsshkey_body() {
atf_check -o inline:"mykey\nmykey\n" cat .ssh/authorized_keys atf_check -o inline:"mykey\nmykey\n" cat .ssh/authorized_keys
} }
adduser_body() { adduser_head()
export NUAGE_FAKE_ROOTDIR="$(pwd)" {
if [ $(id -u) -ne 0 ]; then atf_set "require.user" root
atf_skip "root required" }
fi adduser_body()
{
mkdir etc 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 pwd_mkdb -d etc etc/master.passwd
printf "wheel:*:0:root\n" > etc/group 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" 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 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 mkdir etc
printf "wheel:*:0:root\n" > etc/group 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 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 sethostname
atf_add_test_case addsshkey atf_add_test_case addsshkey
atf_add_test_case adduser atf_add_test_case adduser

View File

@ -1,8 +1,15 @@
#-
# Copyright (c) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
#
# SPDX-License-Identifier: BSD-2-Clause
#
export NUAGE_FAKE_ROOTDIR="$PWD"
atf_test_case args atf_test_case args
atf_test_case nocloud atf_test_case nocloud
atf_test_case nocloud_userdata_script atf_test_case nocloud_userdata_script
atf_test_case nocloud_user_data_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_userdata_cloudconfig_users
atf_test_case nocloud_network atf_test_case nocloud_network
atf_test_case config2 atf_test_case config2
@ -12,72 +19,66 @@ atf_test_case config2_pubkeys_meta_data
atf_test_case config2_network atf_test_case config2_network
atf_test_case config2_network_static_v4 atf_test_case config2_network_static_v4
args_body() args_body()
{ {
atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit <cloud-init directory> [config-2|nocloud]\n" /usr/libexec/nuageinit atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit
atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit <cloud-init directory> [config-2|nocloud]\n" /usr/libexec/nuageinit bla atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<config-2> | <nocloud>)\n" /usr/libexec/nuageinit bla
atf_check -s exit:1 -e inline:"Usage /usr/libexec/nuageinit <cloud-init directory> [config-2|nocloud]\n" /usr/libexec/nuageinit bla meh plop atf_check -s exit:1 -e inline:"Usage: /usr/libexec/nuageinit <cloud-init-directory> (<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() nocloud_body()
{ {
here=$(pwd)
mkdir -p media/nuageinit mkdir -p media/nuageinit
atf_check -s exit:1 -e match:"nuageinit: error parsing nocloud.*" /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
export NUAGE_FAKE_ROOTDIR=$(pwd) printf "instance-id: iid-local01\nlocal-hostname: cloudimg\n" > "${PWD}"/media/nuageinit/meta-data
printf "instance-id: iid-local01\nlocal-hostname: cloudimg\n" > ${here}/media/nuageinit/meta-data atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
atf_check -s exit:0 /usr/libexec/nuageinit ${here}/media/nuageinit nocloud
atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
cat > media/nuageinit/meta-data << EOF cat > media/nuageinit/meta-data << EOF
instance-id: iid-local01 instance-id: iid-local01
hostname: myhost hostname: myhost
EOF 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 atf_check -o inline:"hostname=\"myhost\"\n" cat etc/rc.conf.d/hostname
} }
nocloud_userdata_script_body() nocloud_userdata_script_body()
{ {
here=$(pwd)
mkdir -p media/nuageinit 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
printf "#!/bin/sh\necho "yeah"\n" > ${here}/media/nuageinit/user-data printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user-data
chmod 755 ${here}/media/nuageinit/user-data chmod 755 "${PWD}"/media/nuageinit/user-data
atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit ${here}/media/nuageinit nocloud atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
} }
nocloud_user_data_script_body() nocloud_user_data_script_body()
{ {
here=$(pwd)
mkdir -p media/nuageinit 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
printf "#!/bin/sh\necho "yeah"\n" > ${here}/media/nuageinit/user_data printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user_data
chmod 755 ${here}/media/nuageinit/user_data chmod 755 "${PWD}"/media/nuageinit/user_data
atf_check -s exit:0 -o inline:"yeah\n" /usr/libexec/nuageinit ${here}/media/nuageinit nocloud 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() 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 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 mkdir -p etc
cat > etc/master.passwd <<EOF cat > etc/master.passwd << EOF
root:*:0:0::0:0:Charlie &:/root:/bin/csh root:*:0:0::0:0:Charlie &:/root:/bin/sh
sys:*:1:0::0:0:Sys:/home/sys:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
EOF EOF
pwd_mkdb -d etc ${here}/etc/master.passwd pwd_mkdb -d etc "${PWD}"/etc/master.passwd
cat > etc/group <<EOF cat > etc/group << EOF
wheel:*:0:root wheel:*:0:root
users:*:1: users:*:1:
EOF EOF
cat > media/nuageinit/user-data <<EOF cat > media/nuageinit/user-data << 'EOF'
#cloud-config #cloud-config
groups: groups:
- admingroup: [root,sys] - admingroup: [root,sys]
@ -90,7 +91,7 @@ users:
groups: users groups: users
passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/ passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
EOF EOF
atf_check /usr/libexec/nuageinit ${here}/media/nuageinit nocloud atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
cat > expectedgroup << EOF cat > expectedgroup << EOF
wheel:*:0:root,freebsd wheel:*:0:root,freebsd
users:*:1:foobar users:*:1:foobar
@ -99,34 +100,34 @@ cloud-users:*:1002:
freebsd:*:1003: freebsd:*:1003:
foobar:*:1004: foobar:*:1004:
EOF EOF
cat > expectedpasswd << EOF cat > expectedpasswd << 'EOF'
root:*:0:0::0:0:Charlie &:/root:/bin/csh root:*:0:0::0:0:Charlie &:/root:/bin/sh
sys:*:1:0::0:0:Sys:/home/sys:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
freebsd:freebsd:1001:1003::0:0:FreeBSD User:/home/freebsd:/bin/sh 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 EOF
sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" ${here}/etc/master.passwd sed -i "" "s/freebsd:.*:1001/freebsd:freebsd:1001/" "${PWD}"/etc/master.passwd
atf_check -o file:expectedpasswd cat ${here}/etc/master.passwd atf_check -o file:expectedpasswd cat "${PWD}"/etc/master.passwd
atf_check -o file:expectedgroup cat ${here}/etc/group atf_check -o file:expectedgroup cat "${PWD}"/etc/group
} }
nocloud_network_head()
{
atf_set "require.user" root
}
nocloud_network_body() nocloud_network_body()
{ {
here=$(pwd)
mkdir -p media/nuageinit mkdir -p media/nuageinit
mkdir -p etc mkdir -p etc
cat > etc/master.passwd <<EOF cat > etc/master.passwd << EOF
root:*:0:0::0:0:Charlie &:/root:/bin/csh root:*:0:0::0:0:Charlie &:/root:/bin/sh
sys:*:1:0::0:0:Sys:/home/sys:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
EOF EOF
pwd_mkdb -d etc ${here}/etc/master.passwd pwd_mkdb -d etc "${PWD}"/etc/master.passwd
cat > etc/group <<EOF cat > etc/group << EOF
wheel:*:0:root wheel:*:0:root
users:*:1: users:*:1:
EOF EOF
if [ $(id -u) -ne 0 ]; then
atf_skip "root required"
fi
mynetworks=$(ifconfig -l ether) mynetworks=$(ifconfig -l ether)
if [ -z "$mynetworks" ]; then if [ -z "$mynetworks" ]; then
atf_skip "a network interface is needed" atf_skip "a network interface is needed"
@ -134,112 +135,104 @@ EOF
set -- $mynetworks set -- $mynetworks
myiface=$1 myiface=$1
myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }') 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 cat > media/nuageinit/user-data << EOF
#cloud-config #cloud-config
#
network: network:
version: 2 version: 2
ethernets: ethernets:
# opaque ID for physical interfaces, only referred to by other stanzas # opaque ID for physical interfaces, only referred to by other stanzas
id0: id0:
match: match:
macaddress: '${myaddr}' macaddress: "$myaddr"
addresses: addresses:
- 192.168.14.2/24 - 192.0.2.2/24
- 2001:1::1/64 - 2001:db8::2/64
gateway4: 192.168.14.1 gateway4: 192.0.2.1
gateway6: 2001:1::2 gateway6: 2001:db8::1
EOF EOF
export NUAGE_FAKE_ROOTDIR=$(pwd) atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
atf_check /usr/libexec/nuageinit ${here}/media/nuageinit nocloud cat > network << EOF
cat > network <<EOF ifconfig_${myiface}="inet 192.0.2.2/24"
ifconfig_${myiface}="inet 192.168.14.2/24" ifconfig_${myiface}_ipv6="inet6 2001:db8::2/64"
ifconfig_${myiface}_ipv6="inet6 2001:1::1/64"
ipv6_network_interfaces="${myiface}" ipv6_network_interfaces="${myiface}"
ipv6_default_interface="${myiface}" ipv6_default_interface="${myiface}"
EOF EOF
cat > routing <<EOF cat > routing << EOF
defaultrouter="192.168.14.1" defaultrouter="192.0.2.1"
ipv6_defaultrouter="2001:1::2" ipv6_defaultrouter="2001:db8::1"
ipv6_route_${myiface}="2001:1::2 -prefixlen 128 -interface ${myiface}" ipv6_route_${myiface}="2001:db8::1 -prefixlen 128 -interface ${myiface}"
EOF EOF
atf_check -o file:network cat ${here}/etc/rc.conf.d/network atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
atf_check -o file:routing cat ${here}/etc/rc.conf.d/routing atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
} }
config2_body() config2_body()
{ {
here=$(pwd)
mkdir -p media/nuageinit 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 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 cat > media/nuageinit/meta_data.json << EOF
{ {
"hostname": "cloudimg", "hostname": "cloudimg"
} }
EOF EOF
export NUAGE_FAKE_ROOTDIR=$(pwd) atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2
atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname atf_check -o inline:"hostname=\"cloudimg\"\n" cat etc/rc.conf.d/hostname
} }
config2_pubkeys_head()
{
atf_set "require.user" root
}
config2_pubkeys_body() 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 mkdir -p media/nuageinit
touch media/nuageinit/meta_data.json touch media/nuageinit/meta_data.json
cat > media/nuageinit/user-data << EOF cat > media/nuageinit/user-data << EOF
#cloud-config #cloud-config
ssh_authorized_keys: ssh_authorized_keys:
- "ssh-rsa AAAAB3NzaC1y...== Generated by Nova" - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
EOF EOF
mkdir -p etc mkdir -p etc
cat > etc/master.passwd <<EOF cat > etc/master.passwd << EOF
root:*:0:0::0:0:Charlie &:/root:/bin/csh root:*:0:0::0:0:Charlie &:/root:/bin/sh
sys:*:1:0::0:0:Sys:/home/sys:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
EOF EOF
pwd_mkdb -d etc ${here}/etc/master.passwd pwd_mkdb -d etc "${PWD}"/etc/master.passwd
cat > etc/group <<EOF cat > etc/group << EOF
wheel:*:0:root wheel:*:0:root
users:*:1: users:*:1:
EOF 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 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() 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 mkdir -p media/nuageinit
touch media/nuageinit/meta_data.json touch media/nuageinit/meta_data.json
cat > media/nuageinit/user_data << EOF cat > media/nuageinit/user_data << EOF
#cloud-config #cloud-config
ssh_authorized_keys: ssh_authorized_keys:
- "ssh-rsa AAAAB3NzaC1y...== Generated by Nova" - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
EOF EOF
mkdir -p etc mkdir -p etc
cat > etc/master.passwd <<EOF cat > etc/master.passwd << EOF
root:*:0:0::0:0:Charlie &:/root:/bin/csh root:*:0:0::0:0:Charlie &:/root:/bin/sh
sys:*:1:0::0:0:Sys:/home/sys:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
EOF EOF
pwd_mkdb -d etc ${here}/etc/master.passwd pwd_mkdb -d etc "${PWD}"/etc/master.passwd
cat > etc/group <<EOF cat > etc/group << EOF
wheel:*:0:root wheel:*:0:root
users:*:1: users:*:1:
EOF 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 atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat home/freebsd/.ssh/authorized_keys
} }
@ -251,37 +244,37 @@ config2_pubkeys_meta_data_body()
atf_skip "root required" atf_skip "root required"
fi fi
mkdir -p media/nuageinit mkdir -p media/nuageinit
cat > media/nuageinit/meta_data.json <<EOF cat > media/nuageinit/meta_data.json << EOF
{ {
"uuid": "uuid_for_this_instance", "uuid": "uuid_for_this_instance",
"admin_pass": "a_generated_password", "admin_pass": "a_generated_password",
"public_keys": { "public_keys": {
"tdb": "ssh-ed25519 my_key_id tdb@host" "tdb": "ssh-ed25519 my_key_id tdb@host"
}, },
"keys": [ "keys": [
{ {
"name": "tdb", "name": "tdb",
"type": "ssh", "type": "ssh",
"data": "ssh-ed25519 my_key_id tdb@host" "data": "ssh-ed25519 my_key_id tdb@host"
} }
], ],
"hostname": "freebsd-14-test.novalocal", "hostname": "freebsd-14-test.novalocal",
"name": "freebsd-14-test", "name": "freebsd-14-test",
"launch_index": 0, "launch_index": 0,
"availability_zone": "nova", "availability_zone": "nova",
"random_seed": "long_random_seed", "random_seed": "long_random_seed",
"project_id": "my_project_id", "project_id": "my_project_id",
"devices": [], "devices": [],
"dedicated_cpus": [] "dedicated_cpus": []
} }
EOF EOF
mkdir -p etc mkdir -p etc
cat > etc/master.passwd <<EOF cat > etc/master.passwd << EOF
root:*:0:0::0:0:Charlie &:/root:/bin/csh root:*:0:0::0:0:Charlie &:/root:/bin/csh
sys:*:1:0::0:0:Sys:/home/sys:/bin/csh sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
EOF EOF
pwd_mkdb -d etc ${here}/etc/master.passwd pwd_mkdb -d etc ${here}/etc/master.passwd
cat > etc/group <<EOF cat > etc/group << EOF
wheel:*:0:root wheel:*:0:root
users:*:1: users:*:1:
EOF EOF
@ -289,8 +282,8 @@ EOF
atf_check -o inline:"ssh-ed25519 my_key_id tdb@host\n" cat home/freebsd/.ssh/authorized_keys 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 mkdir -p media/nuageinit
printf "{}" > media/nuageinit/meta_data.json printf "{}" > media/nuageinit/meta_data.json
mynetworks=$(ifconfig -l ether) mynetworks=$(ifconfig -l ether)
@ -300,13 +293,13 @@ config2_network_body() {
set -- $mynetworks set -- $mynetworks
myiface=$1 myiface=$1
myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }') myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
cat > media/nuageinit/network_data.json <<EOF cat > media/nuageinit/network_data.json << EOF
{ {
"links": [ "links": [
{ {
"ethernet_mac_address": "$myaddr", "ethernet_mac_address": "$myaddr",
"id": "iface0", "id": "iface0",
"mtu": null, "mtu": null
} }
], ],
"networks": [ "networks": [
@ -315,49 +308,48 @@ cat > media/nuageinit/network_data.json <<EOF
"link": "iface0", "link": "iface0",
"type": "ipv4_dhcp" "type": "ipv4_dhcp"
}, },
{ // IPv6 { // IPv6
"id": "private-ipv4", "id": "private-ipv4",
"type": "ipv6", "type": "ipv6",
"link": "iface0", "link": "iface0",
// supports condensed IPv6 with CIDR netmask // supports condensed IPv6 with CIDR netmask
"ip_address": "2001:cdba::3257:9652/24", "ip_address": "2001:db8::3257:9652/64",
"gateway": "fd00::1" "gateway": "fd00::1",
"routes": [ "routes": [
{ {
"network": "::", "network": "::",
"netmask": "::", "netmask": "::",
"gateway": "fd00::1" "gateway": "fd00::1"
}, },
{ {
"network": "::", "network": "::",
"netmask": "ffff:ffff:ffff::", "netmask": "ffff:ffff:ffff::",
"gateway": "fd00::1:1" "gateway": "fd00::1:1"
}, }
], ],
"network_id": "da5bb487-5193-4a65-a3df-4a0055a8c0d8" "network_id": "da5bb487-5193-4a65-a3df-4a0055a8c0d8"
}, }
], ]
} }
EOF EOF
export NUAGE_FAKE_ROOTDIR=$(pwd) atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2 cat > network << EOF
cat > network <<EOF
ifconfig_${myiface}="DHCP" 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_network_interfaces="${myiface}"
ipv6_default_interface="${myiface}" ipv6_default_interface="${myiface}"
EOF EOF
cat > routing <<EOF cat > routing << EOF
ipv6_defaultrouter="fd00::1" ipv6_defaultrouter="fd00::1"
ipv6_route_${myiface}="fd00::1 -prefixlen 128 -interface ${myiface}" ipv6_route_${myiface}="fd00::1 -prefixlen 128 -interface ${myiface}"
ipv6_static_routes="${myiface}" ipv6_static_routes="${myiface}"
EOF EOF
atf_check -o file:network cat ${here}/etc/rc.conf.d/network atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
atf_check -o file:routing cat ${here}/etc/rc.conf.d/routing atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
} }
config2_network_static_v4_body() { config2_network_static_v4_body()
here=$(pwd) {
mkdir -p media/nuageinit mkdir -p media/nuageinit
printf "{}" > media/nuageinit/meta_data.json printf "{}" > media/nuageinit/meta_data.json
mynetworks=$(ifconfig -l ether) mynetworks=$(ifconfig -l ether)
@ -367,51 +359,49 @@ config2_network_static_v4_body() {
set -- $mynetworks set -- $mynetworks
myiface=$1 myiface=$1
myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }') myaddr=$(ifconfig $myiface ether | awk '/ether/ { print $2 }')
cat > media/nuageinit/network_data.json <<EOF cat > media/nuageinit/network_data.json << EOF
{ {
"links": [ "links": [
{ {
"ethernet_mac_address": "$myaddr", "ethernet_mac_address": "$myaddr",
"id": "iface0", "id": "iface0",
"mtu": null, "mtu": null
} }
], ],
"networks": [ "networks": [
{ {
"id": "network0", "id": "network0",
"link": "iface0", "link": "iface0",
"type": "ipv4" "type": "ipv4",
"ip_address": "10.184.0.244", "ip_address": "10.184.0.244",
"netmask": "255.255.240.0", "netmask": "255.255.240.0",
"routes": [ "routes": [
{ {
"network": "10.0.0.0", "network": "10.0.0.0",
"netmask": "255.0.0.0", "netmask": "255.0.0.0",
"gateway": "11.0.0.1" "gateway": "11.0.0.1"
}, },
{ {
"network": "0.0.0.0", "network": "0.0.0.0",
"netmask": "0.0.0.0", "netmask": "0.0.0.0",
"gateway": "23.253.157.1" "gateway": "23.253.157.1"
} }
] ]
} }
] ]
} }
EOF EOF
atf_check /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
export NUAGE_FAKE_ROOTDIR=$(pwd) cat > network << EOF
atf_check /usr/libexec/nuageinit ${here}/media/nuageinit config-2
cat > network <<EOF
ifconfig_${myiface}="inet 10.184.0.244 netmask 255.255.240.0" ifconfig_${myiface}="inet 10.184.0.244 netmask 255.255.240.0"
EOF EOF
cat > routing <<EOF cat > routing << EOF
route_cloudinit1_${myiface}="-net 10.0.0.0 11.0.0.1 255.0.0.0" route_cloudinit1_${myiface}="-net 10.0.0.0 11.0.0.1 255.0.0.0"
defaultrouter="23.253.157.1" defaultrouter="23.253.157.1"
static_routes="cloudinit1_${myiface}" static_routes="cloudinit1_${myiface}"
EOF EOF
atf_check -o file:network cat ${here}/etc/rc.conf.d/network atf_check -o file:network cat "${PWD}"/etc/rc.conf.d/network
atf_check -o file:routing cat ${here}/etc/rc.conf.d/routing atf_check -o file:routing cat "${PWD}"/etc/rc.conf.d/routing
} }
atf_init_test_cases() atf_init_test_cases()

View File

@ -1,4 +1,5 @@
#!/usr/libexec/flua #!/usr/libexec/flua
local n = require("nuage") local n = require("nuage")
n.sethostname("myhostname") n.sethostname("myhostname")

View File

@ -1,20 +1,30 @@
#-
# Copyright (c) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
#
# SPDX-License-Identifier: BSD-2-Clause
#
atf_test_case warn atf_test_case warn
atf_test_case err atf_test_case err
atf_test_case dirname 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 {
atf_check -e "inline:nuageinit: 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 {
atf_check -e "inline:nuageinit: 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_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 warn
atf_add_test_case err atf_add_test_case err
atf_add_test_case dirname atf_add_test_case dirname

View File

@ -1,4 +1,5 @@
#!/usr/libexec/flua #!/usr/libexec/flua
local n = require("nuage") local n = require("nuage")
n.warn("plop") n.warn("plop")

View File

@ -1,3 +1,4 @@
---
-- SPDX-License-Identifier: MIT -- SPDX-License-Identifier: MIT
-- --
-- Copyright (c) 2017 Dominic Letz dominicletz@exosite.com -- Copyright (c) 2017 Dominic Letz dominicletz@exosite.com

View File

@ -18,8 +18,8 @@ nuageinit_start()
{ {
local citype local citype
# detect cloud init provider # detect cloud init provider
# according to the specification of the config drive # according to the specification, the config drive
# it either formatted in vfat or iso9660 and labeled # is either formatted in vfat or iso9660 and labeled
# config-2 # config-2
for f in iso9660 msdosfs; do for f in iso9660 msdosfs; do
drive="/dev/$f/[cC][oO][nN][fF][iI][gG]-2" 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" err 1 "Impossible to find a cloud init provider"
fi fi
mkdir -p /media/nuageinit mkdir -p /media/nuageinit
fs=$(fstyp $drive) fs=$(fstyp $drive 2> /dev/null)
mount -t $fs $drive /media/nuageinit mount -t $fs $drive /media/nuageinit
# according to the specification, the content is either # according to the specification, the content is either
# in the openstack or ec2 directory # in the openstack or ec2 directory

View File

@ -1,6 +1,4 @@
#!/bin/sh #!/bin/sh
#
#
# Should be enough for base image, image can be resized in needed # Should be enough for base image, image can be resized in needed
export VMSIZE=5g export VMSIZE=5g
@ -9,13 +7,17 @@ export VMSIZE=5g
export CONFIG_DRIVE=YES export CONFIG_DRIVE=YES
export CONFIG_DRIVE_SIZE=1M 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). # 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() { vm_extra_pre_umount() {
cat << EOF >> ${DESTDIR}/etc/rc.conf cat << EOF >> ${DESTDIR}/etc/rc.conf
dumpdev="AUTO" dumpdev="AUTO"
ifconfig_DEFAULT="DHCP" ifconfig_DEFAULT="SYNCDHCP accept_rtadv"
sshd_enable="YES" sshd_enable="YES"
EOF EOF
@ -25,7 +27,8 @@ beastie_disable="YES"
loader_logo="none" loader_logo="none"
console="comconsole,vidconsole" console="comconsole,vidconsole"
EOF EOF
cat <<EOF >> ${DESTDIR}/etc/ssh/sshd_config
cat << EOF >> ${DESTDIR}/etc/ssh/sshd_config
PasswordAuthentication yes PasswordAuthentication yes
UsePAM no UsePAM no
EOF EOF

View File

@ -677,19 +677,18 @@ static int
gpioc_open(struct cdev *dev, int oflags, int devtype, struct thread *td) gpioc_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{ {
struct gpioc_cdevpriv *priv; struct gpioc_cdevpriv *priv;
int err; int err = 0;
priv = malloc(sizeof(*priv), M_GPIOC, M_WAITOK | M_ZERO); priv = malloc(sizeof(*priv), M_GPIOC, M_WAITOK | M_ZERO);
priv->sc = dev->si_drv1; 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); mtx_init(&priv->mtx, "gpioc priv", NULL, MTX_DEF);
knlist_init_mtx(&priv->selinfo.si_note, &priv->mtx); 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 * Allocate a circular buffer for events. The scheme we use for summary
* reporting assumes there will always be a pair of events available to * 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), priv->events = malloc(priv->numevents * sizeof(struct gpio_event_detail),
M_GPIOC, M_WAITOK | M_ZERO); 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 static int

View File

@ -153,6 +153,7 @@
#include <net/vnet.h> #include <net/vnet.h>
#include <security/mac/mac_framework.h> #include <security/mac/mac_framework.h>
#include <security/mac/mac_internal.h>
#include <vm/uma.h> #include <vm/uma.h>
@ -1485,6 +1486,10 @@ solisten_proto(struct socket *so, int backlog)
sbrcv_timeo = so->so_rcv.sb_timeo; sbrcv_timeo = so->so_rcv.sb_timeo;
sbsnd_timeo = so->so_snd.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)) { if (!(so->so_proto->pr_flags & PR_SOCKBUF)) {
sbdestroy(so, SO_SND); sbdestroy(so, SO_SND);
sbdestroy(so, SO_RCV); sbdestroy(so, SO_RCV);

View File

@ -1372,7 +1372,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
int autoflowlabel = 0; int autoflowlabel = 0;
#endif #endif
#ifdef MAC #ifdef MAC
struct label *maclabel; struct label *maclabel = NULL;
#endif #endif
struct syncache scs; struct syncache scs;
struct ucred *cred; struct ucred *cred;
@ -1763,10 +1763,11 @@ donenoprobe:
tfo_expanded: tfo_expanded:
if (cred != NULL) if (cred != NULL)
crfree(cred); crfree(cred);
if (sc == NULL || sc == &scs) {
#ifdef MAC #ifdef MAC
if (sc == &scs)
mac_syncache_destroy(&maclabel); mac_syncache_destroy(&maclabel);
#endif #endif
}
return (rv); return (rv);
} }

View File

@ -485,6 +485,7 @@ mac_syncache_init(struct label **label)
MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label, MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label,
*label); *label);
mac_labelzone_free(*label); mac_labelzone_free(*label);
*label = NULL;
} }
return (error); return (error);
} else } else

View File

@ -242,6 +242,7 @@ struct label *mac_pipe_label_alloc(void);
void mac_pipe_label_free(struct label *label); void mac_pipe_label_free(struct label *label);
struct label *mac_socket_label_alloc(int flag); struct label *mac_socket_label_alloc(int flag);
void mac_socket_label_free(struct label *label); void mac_socket_label_free(struct label *label);
void mac_socketpeer_label_free(struct label *label);
struct label *mac_vnode_label_alloc(void); struct label *mac_vnode_label_alloc(void);
void mac_vnode_label_free(struct label *label); void mac_vnode_label_free(struct label *label);

View File

@ -170,7 +170,7 @@ mac_socket_label_free(struct label *label)
mac_labelzone_free(label); mac_labelzone_free(label);
} }
static void void
mac_socketpeer_label_free(struct label *label) mac_socketpeer_label_free(struct label *label)
{ {
@ -185,8 +185,10 @@ mac_socket_destroy(struct socket *so)
if (so->so_label != NULL) { if (so->so_label != NULL) {
mac_socket_label_free(so->so_label); mac_socket_label_free(so->so_label);
so->so_label = NULL; so->so_label = NULL;
mac_socketpeer_label_free(so->so_peerlabel); if (!SOLISTENING(so)) {
so->so_peerlabel = NULL; 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); buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
intlabel = mac_socket_label_alloc(M_WAITOK); intlabel = mac_socket_label_alloc(M_WAITOK);
SOCK_LOCK(so); 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); SOCK_UNLOCK(so);
error = mac_socketpeer_externalize_label(intlabel, elements, buffer, if (error == 0) {
mac->m_buflen); error = mac_socketpeer_externalize_label(intlabel, elements, buffer,
mac->m_buflen);
}
mac_socket_label_free(intlabel); mac_socket_label_free(intlabel);
if (error == 0) if (error == 0)
error = copyout(buffer, mac->m_string, strlen(buffer)+1); error = copyout(buffer, mac->m_string, strlen(buffer)+1);