mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-28 09:11:11 -07:00
Name every machine after its own MAC address, and drop mDNS
One name for every machine was wrong: an operator with two of them on a network had one forgefirm.local, and mDNS does not work on many networks at all. The machine now calls itself forgefirm-<xxxx>, from the last four hex digits of its WiFi MAC address, and sends that name with its DHCP request, so a network with dynamic DNS publishes it and a router lists the machine by name. The name is the same at every boot, two machines take different names, and no serial number leaves the machine. forgefirm-hostname (new): reads the wlan0 MAC address (eth0 on a machine with no WiFi) at S38 in rcS, after udev has probed the network drivers and before poky's hostname.sh reads the file and before the network starts. The rootfs is read-only, so the name is written through a bind-mounted copy under /run/forgefirm. A bounded wait covers a slow probe. hostname:pn-base-files is "forgefirm": the name before S38, and the fallback when no MAC address can be read. avahi is deleted - the bbappend, the daemon configuration, the service file, the image install and the distro block. The address is the way in that works on every network, and the DHCP name covers the rest. forgefirm-banner: the marker lines are gone. "# ForgeFIRM addresses" and "# end" delimited the address block inside /etc/issue, and getty prints every line of that file, so both markers were on the console. The script now keeps the image's own text in a second copy under /run/forgefirm, captured once per boot before the first write, and renders the whole banner from it. The block is the addresses alone: no mDNS name. forgefirm-image.bb: the ForgeFIRM mark, under the OpenGlow one the base image carries, with the version on the mark's own last line, right-justified to the mark's last column. The mark is written once and rendered per reader, because /etc/issue is parsed by busybox getty (a backslash or a percent sign starts an escape, so the art goes in with every backslash doubled) while /etc/motd is written out as it is. Widths are measured in columns, not bytes: the color sequences take no room on the screen. /etc/issue.net stays unused - the machine tells a client that has not logged in nothing. Acceptance: commission.mdns-announce is replaced by commission.machine-name, which checks the name against the MAC address, the bind-mounted /etc/hostname, the DHCP client's hostname option, the banner's addresses, and that no mDNS responder is on the image; it covers nothing by design, like the test it replaces. forgectrl.auth gains the own-name Host check and its refusal with a domain on it. image.health checks the /etc/hostname mount and the version on the mark's last line in both files. commission.ssh-until-reboot asserts there is no pre-authentication banner. commission_dark's lens coverage widens to src/lenshome.* so src/lenshome.h is covered; the lint is clean at 83 tests. Pins: forgectrl 0.1.14 (9e5330f, the hostname certificate and the Host rule), meta-openglow ced2af2 (the DHCP hostname option and the motd mark) in the kas lock. Proven on the bench reference, hot-deployed and rebooted (image 20260910000208 dev): hostname forgefirm-b00a from MAC 2c:6b:7d:0d:b0:0a, live and in the bind-mounted file; the DHCP client running with -x hostname:forgefirm-b00a; the console banner and the motd carrying both marks with the version aligned to the mark's last column, no marker line and no .local name; forgectrl regenerating its certificate for the new name. Host tests: 357 forgetest unit tests, forgectrl clean under -Werror, tls_test and sanitize_test.
This commit is contained in:
@@ -48,15 +48,12 @@ IMAGE_INSTALL:append = " grblhal-glowforge forgectrl gfhome gfcloud v4l-utils fw
|
||||
# forgefirm-users: renders the operator account record
|
||||
# (/data/forgefirm/users, written by forgectrl) into the system account
|
||||
# files at boot, before sshd, and on reload; also installs the warning an
|
||||
# interactive root shell prints. forgefirm-banner: keeps the control
|
||||
# panel addresses in the serial-console banner (/etc/issue).
|
||||
# interactive root shell prints. forgefirm-hostname: names the machine
|
||||
# forgefirm-<xxxx> from its MAC address, before the network starts.
|
||||
# forgefirm-banner: keeps the control panel addresses in the
|
||||
# serial-console banner (/etc/issue).
|
||||
# forgefirm-persist: the boot timestamp and the random seed on /data.
|
||||
# avahi-daemon: mDNS, so the panel answers at https://forgefirm.local/
|
||||
# and shows up in service browsers. The daemon is installed by name (the
|
||||
# zeroconf distro feature stays off: it would bring libnss-mdns); the
|
||||
# build options and the configuration are in conf/distro/forgefirm.conf
|
||||
# and recipes-connectivity/avahi.
|
||||
IMAGE_INSTALL:append = " forgefirm-users forgefirm-banner forgefirm-persist avahi-daemon"
|
||||
IMAGE_INSTALL:append = " forgefirm-users forgefirm-hostname forgefirm-banner forgefirm-persist"
|
||||
|
||||
# The rootfs mounts read-only on both images; /data (p3) is the writable
|
||||
# partition. read-only-rootfs is poky's feature for it: the root line of
|
||||
@@ -67,8 +64,9 @@ IMAGE_INSTALL:append = " forgefirm-users forgefirm-banner forgefirm-persist avah
|
||||
# package whose post-install must run on the machine, and the removal of
|
||||
# the packages a read-only rootfs cannot use (shadow, base-passwd,
|
||||
# update-rc.d, update-alternatives; the account files stay). What must
|
||||
# last or change at run time is handled file by file: the account files
|
||||
# and /etc/issue (forgefirm-users, forgefirm-banner), the sshd host keys
|
||||
# last or change at run time is handled file by file: the account files,
|
||||
# /etc/hostname and /etc/issue (forgefirm-users, forgefirm-hostname,
|
||||
# forgefirm-banner), the sshd host keys
|
||||
# (recipes-connectivity/openssh), the timestamp and the random seed
|
||||
# (forgefirm-persist). The facts are on the docs site,
|
||||
# technical/forgefirm/image-and-bsp; scripts/release.sh checks the built
|
||||
@@ -108,8 +106,30 @@ IMAGE_OVERHEAD_FACTOR = "1.0"
|
||||
IMAGE_ROOTFS_EXTRA_SPACE = "40960"
|
||||
IMAGE_ROOTFS_MAXSIZE = "204800"
|
||||
|
||||
# Version stamp: /etc/forgefirm-version (machine-readable), echoed on the
|
||||
# serial-console login prompt (/etc/issue) and at SSH login (motd).
|
||||
# The ForgeFIRM mark and the version stamp:
|
||||
# /etc/forgefirm-version (machine-readable), and, under the OpenGlow mark
|
||||
# the base image carries (base-files, meta-openglow), the ForgeFIRM mark
|
||||
# with the version on its last line, right-justified to the mark's last
|
||||
# column, in the two files a person reads - the serial-console login
|
||||
# prompt (/etc/issue) and the motd, which every login prints, the network
|
||||
# ones included. The mark names the firmware, so the version stands
|
||||
# alone.
|
||||
#
|
||||
# The mark is written once here and rendered for each reader, because the
|
||||
# two files are read by different programs:
|
||||
# /etc/issue busybox getty parses it, and both a backslash and a
|
||||
# percent sign start an escape (libbb/login.c,
|
||||
# print_login_issue). An unrecognized escape prints the
|
||||
# character and swallows the backslash, so the art goes in
|
||||
# with every backslash doubled.
|
||||
# /etc/motd a login writes it out as it is: nothing is doubled.
|
||||
# Both keep their color: a getty passes an escape character through, and
|
||||
# so does a login writing the motd. Only the ssh client escapes one, and
|
||||
# it does that to a banner alone.
|
||||
# The pre-authentication banner (/etc/issue.net) stays unused: the ssh
|
||||
# client prints a control character in a banner as an octal escape, and
|
||||
# the machine tells a client that has not logged in nothing anyway.
|
||||
#
|
||||
# Release images carry the release version; the dev image overrides the
|
||||
# string with the build timestamp (the same DATETIME as the artifact
|
||||
# name) plus a dev tag.
|
||||
@@ -123,9 +143,44 @@ FORGEFIRM_VERSION_STRING ?= "v${FORGEFIRM_RELEASE}"
|
||||
|
||||
write_forgefirm_version() {
|
||||
echo "${FORGEFIRM_VERSION_STRING}" > ${IMAGE_ROOTFS}${sysconfdir}/forgefirm-version
|
||||
echo "ForgeFIRM ${FORGEFIRM_VERSION_STRING}" >> ${IMAGE_ROOTFS}${sysconfdir}/issue
|
||||
|
||||
mark=${WORKDIR}/forgefirm-mark
|
||||
cat > $mark <<'MARK'
|
||||
___ [1;39m___ ___ ___ __ __[0m
|
||||
| __|__ _ _ __ _ ___[1;39m| __|_ _| _ \ \/ |[0m
|
||||
| _/ _ \ '_/ _` / -_) [1;39m_| | || / |\/| |[0m
|
||||
|_|\___/_| \__, \___|[1;39m_| |___|_|_\_| |_|[0m
|
||||
|___/
|
||||
MARK
|
||||
|
||||
# The version rides the mark's own last line, its last character on
|
||||
# the mark's last column: under the FIRM half, in the room the
|
||||
# descender of the Forge half leaves. The mark carries the name, so
|
||||
# the version stands alone. Measured in columns, not in bytes: the
|
||||
# color sequences take no room on the screen, and the doubling below
|
||||
# is undone by the getty that reads it. A version with no room left
|
||||
# keeps one space and runs past the mark rather than being cut.
|
||||
stamped=${WORKDIR}/forgefirm-mark-stamped
|
||||
awk -v v="${FORGEFIRM_VERSION_STRING}" '
|
||||
{ line[NR] = $0
|
||||
bare = $0
|
||||
gsub(/\033\[[0-9;]*m/, "", bare)
|
||||
col[NR] = length(bare)
|
||||
if (col[NR] > w) w = col[NR] }
|
||||
END { for (i = 1; i < NR; i++) print line[i]
|
||||
pad = w - col[NR] - length(v)
|
||||
if (pad < 1) pad = 1
|
||||
gap = ""
|
||||
while (length(gap) < pad) gap = gap " "
|
||||
print line[NR] gap v }' $mark > $stamped
|
||||
|
||||
sed 's|\\|\\\\|g' $stamped >> ${IMAGE_ROOTFS}${sysconfdir}/issue
|
||||
echo "" >> ${IMAGE_ROOTFS}${sysconfdir}/issue
|
||||
echo "ForgeFIRM ${FORGEFIRM_VERSION_STRING}" > ${IMAGE_ROOTFS}${sysconfdir}/motd
|
||||
|
||||
cat $stamped >> ${IMAGE_ROOTFS}${sysconfdir}/motd
|
||||
echo "" >> ${IMAGE_ROOTFS}${sysconfdir}/motd
|
||||
|
||||
rm -f $mark $stamped
|
||||
}
|
||||
write_forgefirm_version[vardepsexclude] += "DATETIME"
|
||||
# No semicolon after a function name here or below (the vardeps rule in
|
||||
|
||||
Reference in New Issue
Block a user