Changeset View
Changeset View
Standalone View
Standalone View
libexec/nuageinit/nuageinit
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/libexec/flua | |||||
-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
-- | |||||
-- Copyright(c) 2022 Baptiste Daroussin <bapt@FreeBSD.org> | |||||
-- | |||||
-- Redistribution and use in source and binary forms, with or without | |||||
-- modification, are permitted provided that the following conditions | |||||
-- are met: | |||||
-- 1. Redistributions of source code must retain the above copyright | |||||
-- notice, this list of conditions and the following disclaimer. | |||||
-- 2. Redistributions in binary form must reproduce the above copyright | |||||
-- notice, this list of conditions and the following disclaimer in the | |||||
-- documentation and/or other materials provided with the distribution. | |||||
-- | |||||
-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
-- SUCH DAMAGE. | |||||
-- $FreeBSD$ | |||||
if #arg ~= 1 then | |||||
print("Usage ".. arg[0] .." <cloud-init directory>") | |||||
os.exit(1) | |||||
end | |||||
path = arg[1] | |||||
local ucl = require("ucl") | |||||
local parser = ucl.parser() | |||||
local res,err = parser:parse_file(path..'/meta_data.json') | |||||
if not res then | |||||
print("Error parsing meta_data.json: " .. err) | |||||
os.exit(1) | |||||
end | |||||
local f = io.popen("getent passwd freebsd") | |||||
local pwd = f:read("*a") | |||||
local homedir = '/home/freebsd' | |||||
if pwd:len() == 0 then | |||||
r = os.execute("pw useradd freebsd -m -M 0755 -w none -n freebsd -G 0 -c 'FreeBSD User' -d '" .. homedir .."' -s '/bin/sh'") | |||||
else | |||||
homedir = pwd:match("%a+:.+:%d+:%d+:.*:(.*):.*") | |||||
end | |||||
local obj = parser:get_object() | |||||
local sshkeys = obj["public_keys"] | |||||
if sshkeys then | |||||
for _,v in pairs(sshkeys) do | |||||
lfs.mkdir("/home/freebsd/.ssh") | |||||
f = io.open("/home/freebsd/.ssh/authorized_keys", "w+") | |||||
f:write(v .. "\n") | |||||
f:close() | |||||
end | |||||
os.execute("chown -R freebsd:freebsd /home/freebsd/.ssh") | |||||
end | |||||
local hostname = obj["hostname"] | |||||
if hostname then | |||||
f = io.open("/etc/rc.conf.d/hostname", "w") | |||||
f:write("hostname=\""..hostname.."\"\n") | |||||
f:close() | |||||
end | |||||
-- network | |||||
parser = ucl.parser() | |||||
local res,err = parser:parse_file(path..'/network_data.json') | |||||
if not res then | |||||
print("Error parsing network_data.json: " .. err) | |||||
os.exit(1) | |||||
end | |||||
obj = parser:get_object() | |||||
-- grab ifaces | |||||
local ns = io.popen('netstat -i --libxo json') | |||||
local netres = ns:read("*a") | |||||
ns:close() | |||||
parser = ucl.parser() | |||||
local res,err = parser:parse_string(netres) | |||||
local ifaces = parser:get_object() | |||||
local myifaces = {} | |||||
for _,iface in pairs(ifaces["statistics"]["interface"]) do | |||||
for o in iface["network"]:gmatch("<Link#%d>") do | |||||
local s = iface["address"]:lower() | |||||
myifaces[s] = iface["name"] | |||||
end | |||||
end | |||||
local mylinks = {} | |||||
for _,v in pairs(obj["links"]) do | |||||
local s = v["ethernet_mac_address"]:lower() | |||||
mylinks[v["id"]] = myifaces[s] | |||||
end | |||||
local network = io.open("/etc/rc.conf.d/network", "w") | |||||
local routing = io.open("/etc/rc.conf.d/routing", "w") | |||||
local ipv6 = {} | |||||
for _,v in pairs(obj["networks"]) do | |||||
if v["type"] == "ipv4_dhcp" then | |||||
network:write("ifconfig_"..mylinks[v["link"]].."=\"DHCP\"\n") | |||||
end | |||||
if v["type"] == "ipv6" then | |||||
table.insert(ipv6, mylinks[v["link"]]) | |||||
network:write("ifconfig_"..mylinks[v["link"]].."_ipv6=\"inet6 "..v["ip_address"].."\"\n") | |||||
routing:write("ipv6_defaultrouter=\""..v["gateway"].."\"\n") | |||||
routing:write("ipv6_route_"..mylinks[v["link"]].."=\""..v["gateway"].." -prefixlen 128 -interface "..mylinks[v["link"]].."\"\n") | |||||
if v["route"] then | |||||
for _,r in v["route"] do | |||||
-- 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 | |||||
print("Not implemented yet") | |||||
os.exit(1) | |||||
::next:: | |||||
end | |||||
end | |||||
end | |||||
end | |||||
network:write("ipv6_network_interfaces=\"") | |||||
for _,v in pairs(ipv6) do | |||||
network:write(v.. " ") | |||||
end | |||||
network:write("\"\n") | |||||
routing:write("ipv6_static_routes=\"") | |||||
for _,v in pairs(ipv6) do | |||||
routing:write(v.. " ") | |||||
end | |||||
routing:write("\"\n") | |||||
network:write("ipv6_default_interface=\""..ipv6[1].."\"\n") | |||||
network:close() | |||||
routing:close() | |||||
local ssh = io.open("/etc/rc.conf.d/sshd", "w+") | |||||
ssh:write("sshd_enable=\"yes\"\n") | |||||
ssh:close() |