From nobody Wed Jan 14 12:31:01 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4drlpG4864z6NLpF for ; Wed, 14 Jan 2026 12:31:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4drlpF6X66z3sWy for ; Wed, 14 Jan 2026 12:31:01 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1768393861; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=CwlNADbqb9FyBiWKFXNqtSQ8g/Jw5IlQfVZJrmx3IM4=; b=nDuWSHcpRnFJGi0xO/N+hnRKlSvBDTo4EBPlW1GSVnLQUPPORdV1+FSEkZFNz0JXkCN9Be dlG3X6bVdPO9ExJ578pnu253JIYzm4Mf7vKnLxWHr4RI1dmP5C79vI57DEKn0c4exnDMzk j2vFr0ns4NEz8aUgvOt45Seu5bEQR77Aq0qjtBKqj6abuR8ZGks45Ql6vBzwGshIMAcR2U gcYjILZ8qptClF8hiQt3kQ7ZvQn5/Lc0EUghUdgt8sejaiAN7XYRtTcCU5HutE/lmoZEhR JlGgfRCfkFJSToJmCeP7+VDc0JkEr33plxZoAw/ZMvRO9Ne28Mgbum2Y7CooXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1768393861; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=CwlNADbqb9FyBiWKFXNqtSQ8g/Jw5IlQfVZJrmx3IM4=; b=qH12AmYAPIcYoWMCYVHHgcWR9CY/TfBKAwa7PgQCNDRNImH8fre/GXiiOSPaV36s8nS9jO vopvrK7wEVWKYxWUkCYeQbOsn3ot4RNcaEv87YwpRuHsZIzQC3OY29WfzQ2F2ULtxVLMvA aQJPltTchOYeh2EohYLkOG5YPTzQgRnKbk1jeUeEf05O0NfaHo/ZAN6ne6rYQL0gbmtG+y 7UNR7DMc94IHq9Jo+jjb4iydxwT1oouAjt6c6EHIvJky3LlvsyT48VdtMiOyq8carCALij Q3xN1sqcE3xFS0WM2Uz2bQPadSJuPAGZ/hV5djyxUcaxBpbyT1HTDjHM1oUEwA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1768393861; a=rsa-sha256; cv=none; b=MQeW0lgT7PpMrWPqQqDkCcdae0GMd//Va8O715RzQPOvus+CaXoEGrgbaidru7Hg8korOQ SNOTZII1pCiWNiac9RRq0XDgJcRvGzgWTzFQlUqI9gxgxSuLNBRA75Rfh6g88+PGGD2FKZ w5aTOXY1DaKnmKmSAJI68aBtuh+uZWmQ0bnaPQDLFSbzuo9pW9sUkNEAo98cGHgUfW7ZZx jxlD4KF08fcYJVFeL+80Zlhe2drP5RisQuHw8iwpj8bllz90FoTMkdExEj3M+yl7u/aROq RIie0DxwA/zeQvDDVimn5E0vv8LLsTZrU8LuGsH2B9eWyyuNg91nwnMJkmOu+w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4drlpF3l8gzxvZ for ; Wed, 14 Jan 2026 12:31:01 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3e2a2 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 14 Jan 2026 12:31:01 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: =?utf-8?Q?Gon=C3=A9ri?= Le Bouder From: Baptiste Daroussin Subject: git: 9d2c4e83c998 - stable/15 - nuageinit: only create the default user when needed List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bapt X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 9d2c4e83c998699e08f6caceede1fc80451c1ff1 Auto-Submitted: auto-generated Date: Wed, 14 Jan 2026 12:31:01 +0000 Message-Id: <69678c85.3e2a2.352ca4cf@gitrepo.freebsd.org> The branch stable/15 has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=9d2c4e83c998699e08f6caceede1fc80451c1ff1 commit 9d2c4e83c998699e08f6caceede1fc80451c1ff1 Author: Gonéri Le Bouder AuthorDate: 2026-01-06 17:18:46 +0000 Commit: Baptiste Daroussin CommitDate: 2026-01-14 12:30:43 +0000 nuageinit: only create the default user when needed The "default" user should only be created when: - the `users` key is missing - or the `default` string is present in the `users` list Since the `public_keys` is extracted from the meta-data, this patch has to slightly adjust the way they are loaded. The change simplify the logic around the default user SSH key injection. Both `ssh_authorized_keys` and `public_keys` are handled at the same time. MFC After: 1 week Signed-off-by: Gonéri Le Bouder Pull Request: https://github.com/freebsd/freebsd-src/pull/1952 (cherry picked from commit cbc00fcc2b92e6e38b0a180261547b1a22b461bd) --- libexec/nuageinit/nuageinit | 150 ++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 62 deletions(-) diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit index aa7d1e4981e6..c36467d2110f 100755 --- a/libexec/nuageinit/nuageinit +++ b/libexec/nuageinit/nuageinit @@ -15,14 +15,28 @@ end local ni_path = arg[1] local citype = arg[2] -local default_user = { - name = "freebsd", - homedir = "/home/freebsd", - groups = "wheel", - gecos = "FreeBSD User", - shell = "/bin/sh", - plain_text_passwd = "freebsd" -} +local function default_user(obj, metadata) + local ssh_authorized_keys = {} + if type(metadata.public_keys) == "table" then + for _, k in pairs(metadata.public_keys) do + table.insert(ssh_authorized_keys, k) + end + end + if type(obj.ssh_authorized_keys) == "table" then + for _, k in ipairs(obj.ssh_authorized_keys) do + table.insert(ssh_authorized_keys, k) + end + end + return { + name = "freebsd", + homedir = "/home/freebsd", + groups = "wheel", + gecos = "FreeBSD User", + shell = "/bin/sh", + plain_text_passwd = "freebsd", + ssh_authorized_keys = ssh_authorized_keys + } +end local root = os.getenv("NUAGE_FAKE_ROOTDIR") if not root then @@ -77,12 +91,16 @@ local function get_ifaces_by_mac() return myifaces end -local function sethostname(obj) +local function sethostname(obj, metadata) -- always prefer fqdn if specified over hostname if obj.fqdn then nuage.sethostname(obj.fqdn) elseif obj.hostname then nuage.sethostname(obj.hostname) + elseif metadata["local-hostname"] then + nuage.sethostname(metadata["local-hostname"]) + elseif metadata["local"] then + nuage.sethostname(metadata["hostname"]) end end @@ -109,20 +127,40 @@ local function groups(obj) end end -local function create_default_user(obj) - if not obj.users then - -- default user if none are defined - nuage.adduser(default_user) +local function create_default_user(obj, metadata) + local function need_default_user() + if not obj.users then + -- default user if "users" is undefined + return true + end + -- create default user if "default" is in the users list + for _, u in pairs(obj.users) do + if type(u) == "string" and u == "default" then + return true + end + end + return false + end + + if need_default_user() then + local du = default_user(obj, metadata) + local homedir = nuage.adduser(du) + if du.ssh_authorized_keys then + for _, k in ipairs(du.ssh_authorized_keys) do + nuage.addsshkey(homedir, k) + end + end end end -local function users(obj) +local function users(obj, metadata) if obj.users == nil then return end for n, u in pairs(obj.users) do if type(u) == "string" then if u == "default" then - nuage.adduser(default_user) + -- already done during create_default_user + nuage.adduser(default_user(obj, metadata)) else nuage.adduser({name = u}) end @@ -179,14 +217,6 @@ local function ssh_keys(obj) end end -local function ssh_authorized_keys(obj) - if obj.ssh_authorized_keys == nil then return end - local homedir = nuage.adduser(default_user) - for _, k in ipairs(obj.ssh_authorized_keys) do - nuage.addsshkey(homedir, k) - end -end - local function nameservers(interface, obj) local resolvconf_conf_handler = open_resolvconf_conf() @@ -279,17 +309,17 @@ local function get_ifaces_by_driver() local drivers = {} local last_interface = nil for line in proc:lines() do - local interface = line:match("^([%S]+): ") + local interface = line:match("^([%S]+): ") - if interface then + if interface then last_interface = interface - end + end - local driver = line:match("^[%s]+drivername: ([%S]+)$") + local driver = line:match("^[%s]+drivername: ([%S]+)$") - if driver then + if driver then drivers[driver] = last_interface - end + end end proc:close() @@ -631,45 +661,42 @@ local function parse_network_config() return netobj end -if citype == "config-2" then - local parser = ucl.parser() - local res, err = parser:parse_file(ni_path .. "/meta_data.json") +local function load_metadata() + if citype == "config-2" then + local parser = ucl.parser() + local res, err = parser:parse_file(ni_path .. "/meta_data.json") - if not res then - nuage.err("error parsing config-2 meta_data.json: " .. err) - end - local obj = parser:get_object() - if obj.public_keys then - local homedir = nuage.adduser(default_user) - for _,v in pairs(obj.public_keys) do - nuage.addsshkey(homedir, v) + if not res then + nuage.err("error parsing config-2 meta_data.json: " .. err) + end + local obj = parser:get_object() + + return obj + elseif citype == "nocloud" then + local f, err = io.open(ni_path .. "/meta-data") + if err then + nuage.err("error parsing nocloud meta-data: " .. err) end + local obj = yaml.load(f:read("*a")) + f:close() + if not obj then + nuage.err("error parsing nocloud meta-data") + end + return obj + elseif citype ~= "postnet" then + nuage.err("Unknown cloud init type: " .. citype) end - nuage.sethostname(obj["hostname"]) + return {} +end + +if citype == "config-2" then -- network config2_network(ni_path) -elseif citype == "nocloud" then - local f, err = io.open(ni_path .. "/meta-data") - if err then - nuage.err("error parsing nocloud meta-data: " .. err) - end - local obj = yaml.load(f:read("*a")) - f:close() - if not obj then - nuage.err("error parsing nocloud meta-data") - end - local hostname = obj["local-hostname"] - if not hostname then - hostname = obj["hostname"] - end - if hostname then - nuage.sethostname(hostname) - end -elseif citype ~= "postnet" then - nuage.err("Unknown cloud init type: " .. citype) end +local metadata = load_metadata() + -- deal with user-data local ud = nil local f = nil @@ -708,7 +735,6 @@ if line == "#cloud-config" then groups, create_default_user, ssh_keys, - ssh_authorized_keys, network_config, ssh_pwauth, runcmd, @@ -739,7 +765,7 @@ if line == "#cloud-config" then local netobj = parse_network_config() or obj network_config(netobj) else - calls_table[i](obj) + calls_table[i](obj, metadata) end end elseif line:sub(1, 2) == "#!" then